通过 jndi 的 MongoDb

发布于 2024-09-29 21:22:52 字数 71 浏览 1 评论 0原文

您知道是否可以在 Spring 中通过 jndi 的数据源像任何其他数据库一样设置 mongodb 实例?

谢谢

Do you know if it is possible to setup mongodb instance in spring like any other db via datasource from jndi?

Thx

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

终遇你 2024-10-06 21:22:52

是的,这是可能的,当您可以创建自己的 JNDI 工厂时,为什么还要依赖别人的代码呢?
只需创建一个实现 javax.naming.spi.ObjectFactory 的类和一个从 JNDI 上下文中提取 mongo 的 bean,我为 spring data-mongo MongoTemplate 对象配置了它。

public class CustomMongoJNDIFactory implements ObjectFactory {

public Object getObjectInstance(Object obj, Name name, Context nameCtx,
        Hashtable<?, ?> environment) throws Exception {

    validateProperty(obj, "Invalid JNDI object reference");

    MongoTemplate mongoTemplate = null;
    String db = null;
    String host = null;
    String username = null;
    String password = null;
    int port = 27017;

    Reference ref = (Reference) obj;
    Enumeration<RefAddr> props = ref.getAll();
    while (props.hasMoreElements()) {
        RefAddr addr = (RefAddr) props.nextElement();
        String propName = addr.getType();
        String propValue = (String) addr.getContent();
        if (propName.equals("db")) {
            db = propValue;
        } else if (propName.equals("host")) {
            host = propValue;
        } else if (propName.equals("username")) {
            username = propValue;
        } else if (propName.equals("password")) {
            password = propValue;
        } else if (name.equals("port")) {
            try {
                port = Integer.parseInt(propValue);
            } catch (NumberFormatException e) {
                throw new NamingException("Invalid port value " + propValue);
            }
        }

    }

    // validate properties
    validateProperty(db, "Invalid or empty mongo database name");
    validateProperty(host, "Invalid or empty mongo host");
    validateProperty(username, "Invalid or empty mongo username");
    validateProperty(password, "Invalid or empty mongo password");

    //create mongo template
    mongoTemplate = new MongoTemplate(new Mongo(host, port), db,
            new UserCredentials(username, password));

    return mongoTemplate;
}


/**
 * Validate internal String properties
 * 
 * @param property
 * @param errorMessage
 * @throws NamingException
 */
private void validateProperty(String property, String errorMessage)
        throws NamingException {
    if (property == null || property.trim().equals("")) {
        throw new NamingException(errorMessage);
    }
}

/**
 * Validate internal Object properties
 * 
 * @param property
 * @param errorMessage
 * @throws NamingException
 */
private void validateProperty(Object property, String errorMessage)
        throws NamingException {
    if (property == null) {
        throw new NamingException(errorMessage);
    }
}

Spring

bean:

@Configuration
@Qualifier("mongoTemplate")
public class CustomMongoTemplate  {


 public @Bean MongoTemplate mongoTemplate() throws Exception {
     Context initCtx = new InitialContext();
     Context envCtx = (Context) initCtx.lookup("java:comp/env");
     return (MongoTemplate) envCtx.lookup("bean/MyMongoBean");
    }
}

Context.xml:

<Resource name="bean/MyMongoBean" auth="Container"
        type="org.springframework.data.mongodb.core.MongoTemplate"
        factory="com.package.CustomMongoJNDIFactory"
        host="" db="" username="" password=""/>

Web.xml

    <resource-env-ref>
    <description>Mongo JNDI configuration</description>
    <resource-env-ref-name>comp/env/bean/MyMongoBean</resource-env-ref-name>
    <resource-env-ref-type>org.springframework.data.mongodb.core.MongoTemplate</resource-env-ref-type>
</resource-env-ref>

Yes it is possible, why relying in someone elses code when you can create your own JNDI factory?
just create a class that implements javax.naming.spi.ObjectFactory and a bean that pulls mongo from the JNDI context, I configured this for spring data-mongo MongoTemplate object.

public class CustomMongoJNDIFactory implements ObjectFactory {

public Object getObjectInstance(Object obj, Name name, Context nameCtx,
        Hashtable<?, ?> environment) throws Exception {

    validateProperty(obj, "Invalid JNDI object reference");

    MongoTemplate mongoTemplate = null;
    String db = null;
    String host = null;
    String username = null;
    String password = null;
    int port = 27017;

    Reference ref = (Reference) obj;
    Enumeration<RefAddr> props = ref.getAll();
    while (props.hasMoreElements()) {
        RefAddr addr = (RefAddr) props.nextElement();
        String propName = addr.getType();
        String propValue = (String) addr.getContent();
        if (propName.equals("db")) {
            db = propValue;
        } else if (propName.equals("host")) {
            host = propValue;
        } else if (propName.equals("username")) {
            username = propValue;
        } else if (propName.equals("password")) {
            password = propValue;
        } else if (name.equals("port")) {
            try {
                port = Integer.parseInt(propValue);
            } catch (NumberFormatException e) {
                throw new NamingException("Invalid port value " + propValue);
            }
        }

    }

    // validate properties
    validateProperty(db, "Invalid or empty mongo database name");
    validateProperty(host, "Invalid or empty mongo host");
    validateProperty(username, "Invalid or empty mongo username");
    validateProperty(password, "Invalid or empty mongo password");

    //create mongo template
    mongoTemplate = new MongoTemplate(new Mongo(host, port), db,
            new UserCredentials(username, password));

    return mongoTemplate;
}


/**
 * Validate internal String properties
 * 
 * @param property
 * @param errorMessage
 * @throws NamingException
 */
private void validateProperty(String property, String errorMessage)
        throws NamingException {
    if (property == null || property.trim().equals("")) {
        throw new NamingException(errorMessage);
    }
}

/**
 * Validate internal Object properties
 * 
 * @param property
 * @param errorMessage
 * @throws NamingException
 */
private void validateProperty(Object property, String errorMessage)
        throws NamingException {
    if (property == null) {
        throw new NamingException(errorMessage);
    }
}

}

Spring bean:

@Configuration
@Qualifier("mongoTemplate")
public class CustomMongoTemplate  {


 public @Bean MongoTemplate mongoTemplate() throws Exception {
     Context initCtx = new InitialContext();
     Context envCtx = (Context) initCtx.lookup("java:comp/env");
     return (MongoTemplate) envCtx.lookup("bean/MyMongoBean");
    }
}

Context.xml:

<Resource name="bean/MyMongoBean" auth="Container"
        type="org.springframework.data.mongodb.core.MongoTemplate"
        factory="com.package.CustomMongoJNDIFactory"
        host="" db="" username="" password=""/>

Web.xml

    <resource-env-ref>
    <description>Mongo JNDI configuration</description>
    <resource-env-ref-name>comp/env/bean/MyMongoBean</resource-env-ref-name>
    <resource-env-ref-type>org.springframework.data.mongodb.core.MongoTemplate</resource-env-ref-type>
</resource-env-ref>
半窗疏影 2024-10-06 21:22:52

复用Juan Melo自定义实现的ObjectFactory接口(CustomMongoJNDIFactory),也可以使用Spring的jee命名空间的jndi-lookup标签和对应的Tomcat进行配置在 context.xml 文件 中配置,如下所示:

spring-mongodb-persistence-context.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mongo="http://www.springframework.org/schema/data/mongo"
       xmlns:jee="http://www.springframework.org/schema/jee"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.2.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd">

    <jee:jndi-lookup id="mongoTemplate" jndi-name="java:/comp/env/jndi/MongoDB" expected-type="org.springframework.data.mongodb.core.MongoTemplate" />

    <mongo:repositories base-package="com.package.repository.mongodb" />

</beans>

context.xml:

<Resource name="jndi/MongoDB"
    auth="Container"
    type="org.springframework.data.mongodb.core.MongoTemplate"
    factory="com.package.mongo.CustomMongoJNDIFactory"
    username="test"
    password="test"
    host="localhost"
    port="27017"
    db="test" />

Reusing Juan Melo's custom implementation of ObjectFactory interface (CustomMongoJNDIFactory), it can be also configured using jndi-lookup tag of Spring's jee namespace and corresponding Tomcat config in context.xml file, like this:

spring-mongodb-persistence-context.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mongo="http://www.springframework.org/schema/data/mongo"
       xmlns:jee="http://www.springframework.org/schema/jee"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.2.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd">

    <jee:jndi-lookup id="mongoTemplate" jndi-name="java:/comp/env/jndi/MongoDB" expected-type="org.springframework.data.mongodb.core.MongoTemplate" />

    <mongo:repositories base-package="com.package.repository.mongodb" />

</beans>

context.xml:

<Resource name="jndi/MongoDB"
    auth="Container"
    type="org.springframework.data.mongodb.core.MongoTemplate"
    factory="com.package.mongo.CustomMongoJNDIFactory"
    username="test"
    password="test"
    host="localhost"
    port="27017"
    db="test" />
小ぇ时光︴ 2024-10-06 21:22:52

为此,您需要 MongoDB 的 JDBC 驱动程序实现。我只找到了一个,它在 MongoDB 页面上被称为“实验性”:GitHub JDBC Driver for MongoDB。

为了解决这个限制,您可以设置一些 Spring bean 并为您的应用程序 DAO 创建一个 MongoDB 实现(这样,您就不需要更改 DAO 接口及其客户端组件)。

本文可能会有所帮助:

To do this, you'll need a JDBC driver impl for MongoDB. I have only found one, and it's referred as "experimental" from the MongoDB page: GitHub JDBC Driver for MongoDB .

to workaroud this limitation, you could setup some Spring beans and create a MongoDB implementation for your application DAO (this way, you won't need to change the DAO interface and it's client components).

This articles may help:

街角迷惘 2024-10-06 21:22:52

如果您的意思是像常规 RDBMS 一样使用 JDBC 访问,那么答案是否定的。

If you mean like regular RDBMS with JDBC access, then the answer is no.

倦话 2024-10-06 21:22:52

还有另一项工作是为 MongoDB 提供 JDBC 驱动程序实现。这里:

https://sourceforge.net/projects/mongojdbcdriver

无论如何都不完整,但希望能提供Java 开发人员很快就会熟悉的 JDBC 实现。

There is another effort to provide a JDBC driver impl for MongoDB. Here:

https://sourceforge.net/projects/mongojdbcdriver

Not complete by any measure, but will hopefully provide a JDBC implementation that is familiar to Java developers soon.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文