1、背景
在springboot整合spring-data-mongodb的时候,使用了spring-boot-starter-data-mongodb依赖,但是spring-boot-starter-data-mongodb本身默认是在application.properties或者yml中配置spring.data.mongodb.uri=mongodb://localhost/test这种方式来实现配置的。
而由于之前springboot用的mongo的配置文件是统一的配置,不仅springboot项目在用,其他项目也在用,只是单纯的改造springboot的mongo工具类,所以不能对原有的配置文件做变更,所以为了整合spring-boot-starter-data-mongodb,只能通过自己实现MongoConfig类的方式注入原配置的方式实现spring-boot-starter-data-mongodb的配置。
2、代码
@Configuration
public class MongoConfig {
@Value("${mongoclient.host}")
private String host;
@Value("${mongoclient.account}")
private String account;
@Value("${mongoclient.password}")
private String password;
@Value("${mongoclient.database}")
private String database;
@Value("${mongoclient.ssl}")
private String ssl;
private List<ServerAddress> getMongoAddressList() {
String[] array = host.split(",");
List<ServerAddress> list = new ArrayList<ServerAddress>();
for (int i = 0; i < array.length; i++) {
String tmp = array[i];
ServerAddress address = new ServerAddress(tmp.split(":")[0], Integer.parseInt(tmp.split(":")[1]));
list.add(address);
}
return list;
}
@Bean
public MongoClientOptions mongoClientOptions () {
MongoClientOptions.Builder builder = MongoClientOptions.builder();
builder.alwaysUseMBeans(false);
builder.connectionsPerHost(800);
builder.requiredReplicaSetName("rs0");
builder.readPreference(ReadPreference.secondaryPreferred());
builder.retryWrites(false);
if (Boolean.valueOf(ssl)) {
builder.socketFactory(SSLSocketFactory.getDefault());
}
MongoClientOptions mongoClientOptions = builder.build();
return mongoClientOptions;
}
@Bean
public MongoClient mongoClient(MongoClientOptions mongoClientOptions) throws UnknownHostException {
if (!StringUtils.isEmpty(account) && !StringUtils.isEmpty(password)) {
MongoCredential credentials = MongoCredential.createMongoCRCredential(account, database,
password.toCharArray());
return new MongoClient(getMongoAddressList(), credentials, mongoClientOptions);
} else {
return new MongoClient(getMongoAddressList(), mongoClientOptions);
}
}
@Bean
@ConditionalOnClass(MongoClient.class)
public MongoTemplate mongoTemplate(MongoClient mongoClient) {
MongoTemplate mongoTemplate = new MongoTemplate(new SimpleMongoDbFactory(mongoClient, database));
return mongoTemplate;
}
}
3、问题
将项目打包之后,运行jar包发现启动报错,报错信息是com.mongodb.MongoSecurityException: Exception authenticating,可以看出这是权限问题,但是账号密码肯定能保证是正确的,因为在mongodb客户端我就是能用该账号进行连接的。后来在看MongoCredential credentials = MongoCredential.createMongoCRCredential(account, database, password.toCharArray());这段代码时找到了问题所在。
因为服务器上的mongodb安装的是3.6.4的版本,所以在生成MongoCredential应该使用createScramSha1Credential,而不是createMongoCRCredential。所以把方法进行替换之后打包,运行jar发现启动没有报错,调用方法成功保存mongo数据。