关于Elasticsearch配置后,springboot集成问题及注意细节:(javax.net.ssl.SSLHandshakeException 异常。)_springboot elasticsearch 不使用ssl
这篇文章,文章即标题
1.记住用户名,密码。
之前文章讲过下载Elasticsearch8.+稳定版保姆级教程
2.在集成过程中,一定要确保!!!Elasticsearch版本和
Spring Data Elasticsearch以及你的springboot版本兼容!!!!不然会改很久,这种兼容问题真的是呆逼问题!!!!
3.配置yml文件或者ymal,记住一定是在spring下!
例如,我这里因为图写文章,为了照顾普遍读者,所以安全文件路径写的绝对路径,实际开发建议其存入静态资源目录
# 注意:Elasticsearch配置必须在此层级(spring.elasticsearch) elasticsearch: uris: \"https://localhost:9200\" username: elastic password: \"ko-up8U_oheXybaWjYkv\" ssl: verification-mode: full # 生产环境用 full,开发可暂时用 none certificate-authorities: \"file:D:/ideaDemo/IDEA_DEMO/HRM3/common/src/main/resources/static/certs/http_ca.crt\"
4.Elasticsearch的配置类要注意,路径,名字,别写错了,要和实体类对得上
package com.example.es.config;import co.elastic.clients.elasticsearch.ElasticsearchClient;import co.elastic.clients.json.jackson.JacksonJsonpMapper;import co.elastic.clients.transport.rest_client.RestClientTransport;import org.apache.http.HttpHost;import org.apache.http.auth.AuthScope;import org.apache.http.auth.UsernamePasswordCredentials;import org.apache.http.impl.client.BasicCredentialsProvider;import org.apache.http.ssl.SSLContextBuilder;import org.elasticsearch.client.RestClient;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.io.ClassPathResource;import javax.net.ssl.SSLContext;import java.io.InputStream;import java.security.cert.CertificateFactory;import java.security.cert.X509Certificate;// 配置类,用于配置Elasticsearch客户端@Configurationpublic class ElasticsearchConfig { // 创建并返回一个RestClient实例,用于与Elasticsearch进行通信 @Bean public RestClient elasticRestClient() throws Exception { // 1. 加载证书(两种方式任选其一) // 方式1:从classpath加载(推荐) InputStream certStream = new ClassPathResource(\"static/certs/http_ca.crt\").getInputStream(); // 方式2:直接使用绝对路径(确保开发和生产环境路径一致) // File certFile = new File(\"D:/ideaDemo/IDEA_DEMO/HRM3/common/src/main/resources/static/certs/http_ca.crt\"); // 2. 构建SSL上下文 CertificateFactory cf = CertificateFactory.getInstance(\"X.509\"); X509Certificate caCert = (X509Certificate) cf.generateCertificate(certStream); SSLContext sslContext = SSLContextBuilder.create() .loadTrustMaterial(null, (chain, authType) -> chain[0].equals(caCert)) .build(); // 3. 配置认证和HTTPS BasicCredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials( AuthScope.ANY, new UsernamePasswordCredentials(\"elastic\", \"ko-up8U_oheXybaWjYkv\") ); return RestClient.builder(HttpHost.create(\"https://localhost:9200\")) .setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder .setSSLContext(sslContext) .setDefaultCredentialsProvider(credsProvider) ) .build(); } // 创建并返回一个ElasticsearchClient实例,用于与Elasticsearch进行交互 @Bean public ElasticsearchClient elasticsearchClient(RestClient restClient) { return new ElasticsearchClient(new RestClientTransport(restClient, new JacksonJsonpMapper())); }}
5.建立索引名字不要乱写,要与实体类一致
package com.example.es.service.impl;import co.elastic.clients.elasticsearch.ElasticsearchClient;import co.elastic.clients.elasticsearch.indices.*;import jakarta.annotation.PostConstruct;import org.springframework.stereotype.Service;import java.io.IOException;@Servicepublic class IndexInitializer { private final ElasticsearchClient client; public IndexInitializer(ElasticsearchClient client) { this.client = client; } @PostConstruct public void initIndex() throws IOException { String indexName = \"employees\"; // 与@Document一致 if (!client.indices().exists(ExistsRequest.of(e -> e.index(indexName))).value()) { client.indices().create(CreateIndexRequest.of(c -> c .index(indexName) .settings(s -> s .numberOfShards(\"1\") .numberOfReplicas(\"0\") ) .mappings(m -> m .properties(\"employeeId\", p -> p.long_(v -> v)) .properties(\"name\", p -> p.text(t -> t .analyzer(\"ik_max_word\") .searchAnalyzer(\"ik_smart\") )) .properties(\"position\", p -> p.text(t -> t .analyzer(\"ik_max_word\") .searchAnalyzer(\"ik_smart\") )) .properties(\"department\", p -> p.keyword(k -> k)) ) )); } }}
6.实体类
package com.example.es.entity;import lombok.Data;import org.springframework.data.annotation.Id;import org.springframework.data.elasticsearch.annotations.*;@Data@Document(indexName = \"employees\") // 确保与初始化代码一致public class EmployeeDocument { @Id private Long employeeId; @Field(type = FieldType.Text, analyzer = \"ik_max_word\") private String name; @Field(type = FieldType.Text, analyzer = \"ik_max_word\") private String position; @Field(type = FieldType.Keyword) private String department;}
7.遇到这个错误不要慌:javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
表明应用程序无法验证它正在连接到的Elasticsearch服务器的SSL证书。
可能的原因
- 自签名证书:如果你的Elasticsearch服务器使用的是自签名证书或者内部证书颁发机构(CA)颁发的证书,并且这个证书不在Java的信任库中,那么Java就无法验证这个证书的有效性。
- 证书过期:Elasticsearch服务器的SSL证书可能已经过期。
- 证书链不完整:Elasticsearch服务器可能没有完整地提供它的证书链,导致Java无法构建完整的信任路径。
- Elasticsearch配置问题:Elasticsearch服务器可能配置错误,导致SSL握手失败。
遇到2.3建议再去生成一个证书,遇到4,就是去看yml(或者其他反正就是配置文件)有没有格式错误,语法错误,特别是缩进!我这里说说1,因为1比较常见,如果你是第一次遇到这种情况,那么恭喜你!!你这会儿看到这里,肯定是崩溃到没办法了.
通常情况,大家的Elasticsearch使用的是自签名证书或内部CA颁发的证书,你需要将该证书添加到Java的信任库中。你可以使用keytool
命令来完成这一步骤
假设你的证书文件名字是叫elasticsearch.crt
,你可以使用以下命令将证书导入到Java的信任库中
方法:Win+X进入管理员终端然后输入:前者是你证书文件路径,后者是你的jdk路径的lib\\security\\cacerts
keytool -import -alias elasticsearch -file D:\\path\\to\\your\\elasticsearch.crt -keystore C:\\Program Files\\Java\\jdk-17.0.14\\lib\\security\\cacerts
注意,它会提示输入密码:默认的Java信任库密码是changeit(建议复制粘贴)
。如果你更改了密码,请使用相应的密码,黑框里不会显示你输入的密码
按照提示操作,确认导入证书。如果成功,您将看到类似“证书已添加到密钥库中”的消息。
-
导入证书后,请重启您的Spring Boot应用程序,再次尝试连接Elasticsearch。
这样处理后,Java的信任库应该能够验证Elasticsearch服务器的SSL证书,从而避免 javax.net.ssl.SSLHandshakeException
异常。
注意:如果您在生产环境中操作,务必小心处理密钥库文件,确保其安全,不要将密码硬编码在脚本中,并定期备份密钥库文件。