我正在编写可在MongoDB数据库中获取数据的Dropwizard微服务。微服务可以正常工作,但是我在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的Resource类是:
@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为null
最佳答案
问题是您正在使用private static final MongoConfiguration configuration = new MongoConfiguration();
在XDAO中创建新配置,而不是使用Dropwizard的run
方法中的配置。
执行此操作时,新配置中的字段host
和db_name
为空,这就是为什么在实例化XDAO
时获得NPE的原因
您需要将从应用程序类中的Dropwizard获得的MongoConfiguration
实例传递给XDAO
,理想情况下,是在创建单例XDAO
时,它对db_name
和host
具有非空值
问题下面的这段代码-您正在创建单例而不给XDAO
配置实例。
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的构造函数中取出
MongoConfiguration
等,具体取决于是否保留initDatabase()
我还建议您将
public static synchronized XDAO getSingleton()
的构造函数更改为MyResource
。资源类似乎不需要配置信息,最好使对XDAO的依赖关系显式(然后,您也不必将XDAO单例保持在XDAO类内的静态字段中)。