跳到主要内容

SimpleReactiveElasticsearchRepository] Constructor threw exception

这个错误的原因可能有好几个,你可以做如下检查: 如果你想找一个直接可用的例子话,你可以使用最近我搭建的这一个:emo-springboot-elasticsearch

1. ElasticSearch的版本比较新,需要SSL链接

在连接elastic search的时候,需要增加sslContext,

你需要先复制ES的证书出来,如果你的ES也是docker搭建的,可以直接通过下面的命令复制出来http_ca.crt 并且放入你的项目中

docker cp es01:/usr/share/elasticsearch/config/certs/http_ca.crt .

然后在代码中,加载这个ca.crt到sslContext中,关键代码就是.usingSsl(getSslContext(), (hostname, session) -> true) 这一行。

, (hostname, session) -> true 这个是可选参数,如果你的代码和ES在同一台电脑,那么不配置这个也可以,如果是不同电脑,那么需要这个参数申明不校验ES的证书。

package run.runnable.demospringbootelasticsearch.config;

import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchConfiguration;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.time.Duration;

/**
* @author Asher
* on 2023/7/25
*/
@Configuration
public class ElasticSearchConfig extends ReactiveElasticsearchConfiguration {

@Value("${spring.profiles.active}")
public String env;

@Value("${elastic.username}")
public String esUsername;

@Value("${elastic.password}")
public String esPassword;

@Value("${elastic.hostAndPort}")
public String esHostAndPort;

@Value("classpath:elastic-search/http_ca.crt")
private Resource elasticCert;

@Autowired
private Environment environment;

@SneakyThrows
@Override
public ClientConfiguration clientConfiguration() {
return ClientConfiguration.builder()
.connectedTo(esHostAndPort)
//指定sslContext, 接受elastic search的证书
.usingSsl(getSslContext(), (hostname, session) -> true)
.withConnectTimeout(Duration.ofSeconds(5))
.withSocketTimeout(Duration.ofSeconds(30))
.withBasicAuth(esUsername, esPassword)
.build();
}

/**
* getSslContext
* @return
* @throws CertificateException
* @throws IOException
* @throws KeyStoreException
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
private SSLContext getSslContext()
throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException {

Certificate ca = CertificateFactory.getInstance("X.509")
.generateCertificate(elasticCert.getInputStream());

// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);

// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);

// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
return context;
}
}

你可以在这里找到Spring更加详细的解释,Client Configuration

2. 检查IDE最底下打印的异常,可能会得到更多错误信息供你判断,即使所有异常中也包含了Constructor threw exception

3. 你的xxxRepository有问题

检查对应的对象中的@Document@Field

4. 参考内容

Install Elasticsearch With Docker

Android: Adding trusted CAs