关于Elasticsearch配置后,springboot集成问题及注意细节:(javax.net.ssl.SSLHandshakeException 异常。)
这篇文章,文章即标题
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客户端
@Configuration
public 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;
@Service
public 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 异常。
注意:如果您在生产环境中操作,务必小心处理密钥库文件,确保其安全,不要将密码硬编码在脚本中,并定期备份密钥库文件。
更多推荐


所有评论(0)