springBoot發(fā)布https服務(wù)及調(diào)用的過(guò)程詳解
一、服務(wù)端發(fā)布https服務(wù)
1、準(zhǔn)備SSL證書(shū)
(1)自簽名證書(shū):如果你只是用于開(kāi)發(fā)或測(cè)試環(huán)境,可以生成一個(gè)自簽名證書(shū)。
(2)CA 簽名證書(shū):對(duì)于生產(chǎn)環(huán)境,應(yīng)該使用由受信任的證書(shū)頒發(fā)機(jī)構(gòu) (CA) 簽名的證書(shū)。
這里采用生成自簽名證書(shū),可以使用keytool工具生成自簽名證書(shū)(jdk工具):
keytool -genkeypair -alias myapp -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore keystore.p12 -validity 3650
這將創(chuàng)建一個(gè)有效期為 10 年的自簽名證書(shū),并將其存儲(chǔ)在 keystore.p12 文件中。你需要提供一些信息,如組織名稱等。注意記住密碼和別名。
如下圖:

2、配置springboot啟用HTTPS并指定SSL證書(shū)的位置和密碼
用application.properties 或 application.yml都可以。這樣配置可以讀取環(huán)境變量
把證書(shū)放在resource的ssl目錄下
server:
port: 8443
ssl:
enabled: ${SSL_ENABLED:true}
key-store: ${SSL_KEY_STORE:classpath:ssl/keystore.p12}
key-store-password: ${SSL_KEY_STORE_PASSWORD:myapptest}
keyStoreType: ${SSL_KEY_STORE_TYPE:PKCS12}
keyAlias: ${SSL_KEY_ALIAS:myapp}
啟動(dòng)服務(wù)即可通過(guò)https訪問(wèn)了,默認(rèn)可以設(shè)置成false
3、配置docker容器,啟動(dòng)https
把證書(shū)放在ssl目錄下
version: "3"
services:
test-https:
image: openjdk:8-jdk
container_name: test-https
restart: always
ports:
- 22443:22443
command: java -jar /opt/test-https.jar
volumes:
- /home/services/test/:/opt/
- /home/services/test/config/:/config/
- /home/services/test/ssl/:/ssl/
- /home/services/test/template_server/:/template_server/
- /home/services/test/patch/:/patch/
- /home/log/test/:/logs/
environment:
- TZ=Asia/Shanghai
- SERVICE_HOST=${HOST_IP}
- server.port=22443
- NACOS_NAMESPACE=${NACOS_NAMESPACE}
- NACOS_ADDR=${NACOS_ADDR}
#開(kāi)啟https,如果不開(kāi)啟則配置為false
- SSL_ENABLED=true
#以下配置根據(jù)實(shí)際證書(shū)配置
- SSL_KEY_STORE=ssl/keystore.p12
- SSL_KEY_STORE_PASSWORD=myapptest
- SSL_KEY_STORE_TYPE=PKCS12
- SSL_KEY_ALIAS=myapp
- JAVA_OPTS=-Xmx512m -XX:G1ConcRefinementThreads=4 -XX:MaxDirectMemorySize=1G二、通過(guò)httpinvoke方法https服務(wù)
跳過(guò)證書(shū)校驗(yàn)
public class HttpInvokerRequestExecutorWithSession extends SimpleHttpInvokerRequestExecutor {
private int connectTimeout=0;
private int readTimeout=0;
private SSLContext sslContext;
private HostnameVerifier hostnameVerifier;
private void initSsl() {
try {
sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
}}, new SecureRandom());
} catch (KeyManagementException | NoSuchAlgorithmException e) {
logger.error("ssl init error:",e);
throw new MsrRuntimeException(e.getMessage());
}
hostnameVerifier = (hostname, session) -> true;
}
/**
*
* (non-Javadoc)
*
* @see org.springframework.remoting.httpinvoker.SimpleHttpInvokerRequestExecutor
* #prepareConnection(java.net.HttpURLConnection, int)
*/
protected void prepareConnection(HttpURLConnection con, int contentLength) throws IOException {
super.prepareConnection(con, contentLength);
if (con instanceof HttpsURLConnection) {
if (sslContext == null) {
initSsl();
}
((HttpsURLConnection) con).setSSLSocketFactory(sslContext.getSocketFactory());
((HttpsURLConnection) con).setHostnameVerifier(hostnameVerifier);
}
con.setConnectTimeout(connectTimeout);
con.setReadTimeout(readTimeout);
}
/**
*
* (non-Javadoc)
*
* @see org.springframework.remoting.httpinvoker.SimpleHttpInvokerRequestExecutor
* #validateResponse(org.springframework.remoting.httpinvoker.HttpInvokerClientConfiguration,
* java.net.HttpURLConnection)
*/
protected void validateResponse(HttpInvokerClientConfiguration config, HttpURLConnection con)
throws IOException {
super.validateResponse(config, con);
}
public int getConnectTimeout() {
return connectTimeout;
}
public void setConnectTimeout(int connectTimeout) {
this.connectTimeout = connectTimeout;
}
public int getReadTimeout() {
return readTimeout;
}
public void setReadTimeout(int readTimeout) {
this.readTimeout = readTimeout;
}
}三、feign接口調(diào)用https服務(wù)
跳過(guò)證書(shū)校驗(yàn)。feign接口的地址還是正常配置http或https都支持
import feign.Client;
import feign.Contract;
import feign.RequestInterceptor;
import feign.codec.ErrorDecoder;
import feign.jaxrs.JAXRSContract;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;
@Configuration
public class FeignConfiguration {
@Autowired
private BusinessConfig businessConfig;
/**
* yaml中的配置未生效,暫時(shí)在配置類中配置
*/
@Bean
public Contract getFeignContract() {
return new JAXRSContract();
}
@Bean
public ErrorDecoder getFeignErrorDecoder() {
return new FeignExceptionDecoder();
}
@Bean
public OkHttpClient okHttpClient() {
if(businessConfig.getRootServiceUrl() != null && businessConfig.getRootServiceUrl().contains("https")){
try {
TrustManager[] trustManagers = getTrustManager();
if (trustManagers == null || trustManagers.length == 0) {
throw new IllegalStateException("Failed to create trust managers");
}
SSLSocketFactory sslSocketFactory = getSSLSocketFactory();
if (sslSocketFactory == null) {
throw new IllegalStateException("Failed to initialize SSL socket factory");
}
return new OkHttpClient.Builder()
.readTimeout(60, TimeUnit.SECONDS)
.connectTimeout(60, TimeUnit.SECONDS)
.writeTimeout(120, TimeUnit.SECONDS)
.connectionPool(new ConnectionPool())
.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustManagers[0])
.hostnameVerifier((hostname, session) -> true)
.build();
} catch (Exception e) {
throw new RuntimeException("Failed to create OkHttpClient", e);
}
}
return new OkHttpClient.Builder()
.readTimeout(60, TimeUnit.SECONDS)
.connectTimeout(60, TimeUnit.SECONDS)
.writeTimeout(120, TimeUnit.SECONDS)
.connectionPool(new ConnectionPool())
.build();
}
@Bean
public RequestInterceptor requestInterceptor() {
return new CustomRequestInterceptor(businessConfig);
}
@Bean
public Client feignClient(OkHttpClient okHttpClient) {
return new CustomClient(new feign.okhttp.OkHttpClient(okHttpClient));
}
private TrustManager[] getTrustManager() {
try {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
}
};
return trustAllCerts;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private SSLSocketFactory getSSLSocketFactory() {
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, getTrustManager(), new SecureRandom());
return sc.getSocketFactory();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}到此這篇關(guān)于springBoot發(fā)布https服務(wù)及調(diào)用的過(guò)程詳解的文章就介紹到這了,更多相關(guān)springBoot發(fā)布https服務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
String類型轉(zhuǎn)localDate,date轉(zhuǎn)localDate的實(shí)現(xiàn)代碼
這篇文章主要介紹了String類型轉(zhuǎn)localDate,date轉(zhuǎn)localDate的實(shí)現(xiàn)代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08
Java實(shí)戰(zhàn)之校園外賣點(diǎn)餐系統(tǒng)的實(shí)現(xiàn)
這篇文章主要介紹了如何利用Java實(shí)現(xiàn)簡(jiǎn)易的校園外賣點(diǎn)餐系統(tǒng),文中采用的技術(shù)有:JSP、Spring、SpringMVC、MyBatis 等,感興趣的可以了解一下2022-03-03
Minio分布式集群如何實(shí)現(xiàn)替換一個(gè)節(jié)點(diǎn)
這篇文章主要介紹了Minio分布式集群如何實(shí)現(xiàn)替換一個(gè)節(jié)點(diǎn)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-05-05
java連接SQL?Server數(shù)據(jù)庫(kù)圖文教程(自用)
在Java應(yīng)用程序中,我們經(jīng)常需要與數(shù)據(jù)庫(kù)進(jìn)行交互,下面這篇文章主要給大家介紹了關(guān)于java連接SQL?Server數(shù)據(jù)庫(kù)的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-06-06
Java中的stream流的概念解析及實(shí)際運(yùn)用總結(jié)
流是指?jìng)鬏敃r(shí)的數(shù)據(jù),Java為流準(zhǔn)備了很多內(nèi)置類,尤其是IO輸入輸出流非常常用,這里我們來(lái)看一下Java中的stream流的概念解析及實(shí)際運(yùn)用總結(jié)2016-06-06
java學(xué)生信息管理系統(tǒng)設(shè)計(jì)(2)
這篇文章主要為大家詳細(xì)介紹了java學(xué)生信息管理系統(tǒng)設(shè)計(jì),學(xué)生信息添加進(jìn)入數(shù)據(jù)庫(kù)的事務(wù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11

