Java 在与MongoDB数据库建立连接的方法中使用Dropwizard配置

Java 在与MongoDB数据库建立连接的方法中使用Dropwizard配置,java,mongodb,dropwizard,mongodb-java,Java,Mongodb,Dropwizard,Mongodb Java,我正在编写Dropwizard micro服务,用于在MongoDB数据库中获取数据。微服务工作正常,但我很难在DAO中使用来自Dropwizard配置Java类的配置。目前我有 public class XDAO implements IXDAO { protected DB db; protected DBCollection collection; /* singleton */ private static XDAO instance; /*

我正在编写Dropwizard micro服务,用于在MongoDB数据库中获取数据。微服务工作正常,但我很难在DAO中使用来自Dropwizard配置Java类的配置。目前我有

public class XDAO implements IXDAO {

    protected DB db;
    protected DBCollection collection;

    /* singleton */
    private static XDAO instance;

    /* Get singleton */
    public static synchronized XDAO getSingleton(){
       if (instance == null){
         instance = new XDAO();
       }       
      return instance;
    }

    /* constructor */
    public XDAO(){
       initDatabase();
       initDatabaseIndexes();
    }

    private void initDatabase(){
       MongoClient client = null;

       try {
           client = new Mongo("10.126.80.192",27017); 
           db = client.getDB("terre");
           //then some other code
       }

       catch (final MongoException e){
         ...
       }

       catch (UnknownHostException e){
         ...
       }

     }

 }
我想取消对这两行中的三个参数的编码:

  client = new Mongo("10.126.80.192", 27017); 
  db = client.getDB("terre");
我的MongoConfiguration Java类是:

public class MongoConfiguration extends Configuration {

@JsonProperty
@NotEmpty
public String host;

@JsonProperty
public int port = 27017;

@JsonProperty
@NotEmpty
public String db_name;

public String getMongohost() {
    return host;
}

public void setMongohost(String host) {
    this.host = host;
}

public int getMongoport() {
    return port;
}

public void setMongoport(int port) {
    this.port = port;
}

public String getDb_name() {
    return db_name;
}

public void setDb_name(String db_name) {
    this.db_name = db_name;
}

}
我使用DAO的资源类是:

@Path("/mongo")
@Produces(MediaType.APPLICATION_JSON)
public class MyResource {

private XDAO xDAO = XDAO.getSingleton();

private String mongohost;
private String db_name;
private int mongoport;

public MyResource(String db_name, String mongohost, int mongoport) {
    this.db_name = db_name;
    this.mongohost = mongohost;
    this.mongoport = mongoport;
}

public MyResource() {
}

@GET
@Path("/findByUUID")
@Produces(value = MediaType.APPLICATION_JSON)
@Timed
public Entity findByUUID(@QueryParam("uuid") String uuid) {

    return xDAO.findByUUid(uuid);
  }
}
在我的申请课上有

  @Override
  public void run(final MongoConfiguration configuration, final Environment environment) {

    final MyResource resource = new MyResource(configuration.getDb_name(), configuration.getMongohost(), configuration.getMongoport());
    environment.jersey().register(resource);
   }
为了解决我的问题,我尝试了很多事情。我最后尝试的是在XDAO中添加这四个字段

  private String mongohost;
  private String db_name;
  private int mongoport;
  private static final MongoConfiguration configuration = new MongoConfiguration();
在XDAO的构造函数中附带这段代码:

public XDAO(){
    instance.mongohost = configuration.getMongohost();
    instance.mongoport = configuration.getMongoport();
    instance.db_name = configuration.getDb_name();
    /* then like before */
    initDatabase();
    initDatabaseIndexes();
}

当我尝试此操作时,当调用initDatabase方法时,我会出现一个空指针异常:mongoHost和db_name为空

问题是您正在XDAO中使用
私有静态最终MongoConfiguration configuration=new MongoConfiguration()创建一个新配置
而不是使用Dropwizard的config from-Dropwizard的
run
方法

执行此操作时,新配置中的
host
db_name
字段为空,这就是在实例化
XDAO

您需要将从应用程序类中的Dropwizard中获得的
MongoConfiguration
实例传递到
XDAO
,理想情况下是在创建singleton
XDAO
时,使其具有
db_name
host
的非空值

下面的代码是问题的一部分-您正在创建singleton,而没有提供
XDAO
MongoConfigurationconfiguration实例

public class XDAO implements IXDAO {

//... snip

/* Get singleton */
public static synchronized XDAO getSingleton(){
   if (instance == null){
     instance = new XDAO(); // no configuration information is included!
   }       
  return instance;
}

/* constructor */
public XDAO(){
   initDatabase(); // this call needs db_name & host but you haven't set those yet!!
   initDatabaseIndexes();
}
我建议您修改应用程序类以创建XDAO,方法如下:

@Override
public void run(final MongoConfiguration configuration, final Environment environment) {

  XDAO XDAOsingleton = new XDAO(configuration);
  XDAO.setSingletonInstance(XDAOsingleton); // You need to create this static method.

  final MyResource resource = new MyResource(configuration.getDb_name(), configuration.getMongohost(), configuration.getMongoport()); // MyResource depends on XDAO so must be created after XAO's singleton is set
  environment.jersey().register(resource);
}
根据是否保持公共静态同步XDAO getSingleton()


我还建议您将
MyResource
的构造函数更改为
publicmyresource(XDAO-XDAO)
。资源类似乎不需要配置信息,最好将对XDAO的依赖关系显式化(这样也不需要将XDAO单例保存在XDAO类的静态字段中).

问题是您正在XDAO中使用
私有静态最终MongoConfiguration=new MongoConfiguration()创建新配置
而不是使用Dropwizard的config from-Dropwizard的
run
方法

执行此操作时,新配置中的
host
db_name
字段为空,这就是在实例化
XDAO

您需要将从应用程序类中的Dropwizard中获得的
MongoConfiguration
实例传递到
XDAO
,理想情况下是在创建singleton
XDAO
时,使其具有
db_name
host
的非空值

下面的代码是问题的一部分-您正在创建singleton,而没有提供
XDAO
MongoConfigurationconfiguration实例

public class XDAO implements IXDAO {

//... snip

/* Get singleton */
public static synchronized XDAO getSingleton(){
   if (instance == null){
     instance = new XDAO(); // no configuration information is included!
   }       
  return instance;
}

/* constructor */
public XDAO(){
   initDatabase(); // this call needs db_name & host but you haven't set those yet!!
   initDatabaseIndexes();
}
我建议您修改应用程序类以创建XDAO,方法如下:

@Override
public void run(final MongoConfiguration configuration, final Environment environment) {

  XDAO XDAOsingleton = new XDAO(configuration);
  XDAO.setSingletonInstance(XDAOsingleton); // You need to create this static method.

  final MyResource resource = new MyResource(configuration.getDb_name(), configuration.getMongohost(), configuration.getMongoport()); // MyResource depends on XDAO so must be created after XAO's singleton is set
  environment.jersey().register(resource);
}
根据是否保持公共静态同步XDAO getSingleton()


我还建议您将
MyResource
的构造函数更改为
publicmyresource(XDAO-XDAO)
。资源类似乎不需要配置信息,最好将对XDAO的依赖性显式化(这样也就不需要将XDAO单例保存在XDAO类的静态字段中)。

要以简单的方式集成MongoDB以Dropwizard,请尝试使用MongoDB托管对象。我将用3个简单的步骤来解释这一点:

步骤1:创建一个简单的MongoManged类:

import com.mongodb.Mongo;
import io.dropwizard.lifecycle.Managed;

public class MongoManaged implements Managed {

private Mongo mongo;

public MongoManaged(Mongo mongo) {
    this.mongo = mongo;
}

@Override
public void start() throws Exception {
}

@Override
public void stop() throws Exception {
    mongo.close();
}
}
步骤2:在配置yml文件中提及MongoDB主机、端口、DB名称:

mongoHost : localhost
mongoPort : 27017
mongoDB : softwaredevelopercentral
步骤3:将应用程序类中的所有内容绑定在一起:

public class DropwizardMongoDBApplication extends Application<DropwizardMongoDBConfiguration> {

private static final Logger logger = LoggerFactory.getLogger(DropwizardMongoDBApplication.class);

public static void main(String[] args) throws Exception {
    new DropwizardMongoDBApplication().run("server", args[0]);
}

@Override
public void initialize(Bootstrap<DropwizardMongoDBConfiguration> b) {
}

@Override
public void run(DropwizardMongoDBConfiguration config, Environment env)
        throws Exception {
    MongoClient mongoClient = new MongoClient(config.getMongoHost(), config.getMongoPort());
    MongoManaged mongoManaged = new MongoManaged(mongoClient);
    env.lifecycle().manage(mongoManaged);
    MongoDatabase db = mongoClient.getDatabase(config.getMongoDB());
    MongoCollection<Document> collection = db.getCollection(config.getCollectionName());
    logger.info("Registering RESTful API resources");
    env.jersey().register(new PingResource());
    env.jersey().register(new EmployeeResource(collection, new MongoService()));
    env.healthChecks().register("DropwizardMongoDBHealthCheck",
            new DropwizardMongoDBHealthCheckResource(mongoClient));
}
}
公共类DropwizardMongoDBApplication扩展应用程序{
私有静态最终记录器Logger=LoggerFactory.getLogger(DropwizardMongoDBApplication.class);
公共静态void main(字符串[]args)引发异常{
新建DropwizardMongoDBApplication()。运行(“服务器”,参数[0]);
}
@凌驾
公共无效初始化(引导b){
}
@凌驾
公共无效运行(DropwizardMongoDBConfiguration配置,环境环境)
抛出异常{
MongoClient MongoClient=新的MongoClient(config.getMongoHost(),config.getMongoPort());
MongoManaged MongoManaged=新的MongoManaged(mongoClient);
env.lifecycle().manage(mongoManaged);
MongoDatabase db=mongoClient.getDatabase(config.getMongoDB());
MongoCollection collection=db.getCollection(config.getCollectionName());
info(“注册RESTful API资源”);
env.jersey().register(new PingResource());
jersey环境()注册(新员工资源(集合,新MongoService());
env.healthChecks().register(“DropwizardMongoDBHealthCheck”,
新DropwizardMongoDBHealthCheckResource(mongoClient));
}
}

我使用了这些步骤,写了一篇博客文章,GitHub上提供了一个示例工作应用程序代码。请检查:

要以一种简单的方式将MongoDB集成到Dropwizard中,请尝试使用MongoDB托管对象。我将用3个简单的步骤来解释这一点:

步骤1:创建一个简单的MongoManged类:

import com.mongodb.Mongo;
import io.dropwizard.lifecycle.Managed;

public class MongoManaged implements Managed {

private Mongo mongo;

public MongoManaged(Mongo mongo) {
    this.mongo = mongo;
}

@Override
public void start() throws Exception {
}

@Override
public void stop() throws Exception {
    mongo.close();
}
}
步骤2:在配置yml文件中提及MongoDB主机、端口、DB名称:

mongoHost : localhost
mongoPort : 27017
mongoDB : softwaredevelopercentral
步骤3:将应用程序类中的所有内容绑定在一起:

public class DropwizardMongoDBApplication extends Application<DropwizardMongoDBConfiguration> {

private static final Logger logger = LoggerFactory.getLogger(DropwizardMongoDBApplication.class);

public static void main(String[] args) throws Exception {
    new DropwizardMongoDBApplication().run("server", args[0]);
}

@Override
public void initialize(Bootstrap<DropwizardMongoDBConfiguration> b) {
}

@Override
public void run(DropwizardMongoDBConfiguration config, Environment env)
        throws Exception {
    MongoClient mongoClient = new MongoClient(config.getMongoHost(), config.getMongoPort());
    MongoManaged mongoManaged = new MongoManaged(mongoClient);
    env.lifecycle().manage(mongoManaged);
    MongoDatabase db = mongoClient.getDatabase(config.getMongoDB());
    MongoCollection<Document> collection = db.getCollection(config.getCollectionName());
    logger.info("Registering RESTful API resources");
    env.jersey().register(new PingResource());
    env.jersey().register(new EmployeeResource(collection, new MongoService()));
    env.healthChecks().register("DropwizardMongoDBHealthCheck",
            new DropwizardMongoDBHealthCheckResource(mongoClient));
}
}
公共类DropwizardMongoDBApplication扩展应用程序{
私有静态最终记录器Logger=LoggerFactory.getLogger(DropwizardMongoDBApplication.class);
公共静态voi