1.首先去騰訊雲或者阿里雲申請免費ssl證書,以騰訊雲為例,不建議自己生成,因為沒辦法測試發布環境的效果,填寫個人信息,最后提示審核中才是申請成功,審核比較快,半小時就通過了。

2.下載已經通過審核的證書文件夾,解壓文件如下,根據項目選擇使用:

3.因為springboot使用的是內置tomcat,所以我這邊選擇tomcat文件,在resources目錄下導入xxx.jks

4.接下來配置properties文件,密碼在同文件夾的keystorePass.txt中(騰訊雲)

5.個人比較喜歡yml格式,簡潔直觀(阿里雲)

6.到這個時候基本配置完成,但不能使用https后就通知所有人重新保存網址,這時候就需要增加請求轉發,自動從http轉到https
寫法一:在啟動類也就是@SpringBootApplication注解類中加上使用
/** * http重定向到https * @return */ @Bean public TomcatServletWebServerFactory servletContainer() { TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() { @Override protected void postProcessContext(Context context) { SecurityConstraint constraint = new SecurityConstraint(); constraint.setUserConstraint("CONFIDENTIAL"); SecurityCollection collection = new SecurityCollection(); collection.addPattern("/*"); constraint.addCollection(collection); context.addConstraint(constraint); } }; tomcat.addAdditionalTomcatConnectors(httpConnector()); return tomcat; } @Bean public Connector httpConnector() { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); connector.setScheme("http"); //Connector監聽的http的默認端口號 connector.setPort(8080); connector.setSecure(false); //監聽到http的端口號后轉向到的https的端口號,也就是項目配置的port connector.setRedirectPort(8089); return connector; }
寫法二:另外新建一個配置類,加上@Configuration注解聲明
@Configuration public class TomcatConfig { @Bean TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() { TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory(){ @Override protected void postProcessContext(Context context) { SecurityConstraint constraint = new SecurityConstraint(); constraint.setUserConstraint("CONFIDENTIAL"); SecurityCollection collection = new SecurityCollection(); collection.addPattern("/*"); constraint.addCollection(collection); context.addConstraint(constraint); } }; factory.addAdditionalTomcatConnectors(createTomcatConnector()); return factory; } private Connector createTomcatConnector() { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); connector.setScheme("http"); connector.setPort(5001); connector.setSecure(false); connector.setRedirectPort(443); return connector; } }
7.現在可以通過https://域名:8089/index訪問,這樣就看到熟悉的小鎖了

注意:RestTemplate設置headers,訪問https實現ssl請求參考:https://www.jianshu.com/p/beafe38428c7
application.properties配置:
#遠程調用uri及ssl設置 httpClientUri=https://192.168.3.110:8081 #類型 httpClientSSL.keyStoreType=JKS #classpath下的文件名 httpClientSSL.keyFile= easyView.keystore #證書密碼 httpClientSSL.keyPassword=xxxx

下面是自己封裝的調用方法:
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.TrustSelfSignedStrategy; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.ssl.SSLContexts; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.ClassPathResource; import org.springframework.http.*; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import javax.net.ssl.SSLContext; import java.io.FileInputStream; import java.io.InputStream; import java.security.KeyStore; import java.util.Objects; import java.util.function.Consumer; /** * @date 2020/11/04 */ @Component public class HttpsUtil { private static Logger logger = LoggerFactory.getLogger(HttpsUtil.class); @Value("${httpClientSSL.keyStoreType}") private String keyStoreType; @Value("${httpClientSSL.keyFile}") private String keyFile; @Value("${httpClientSSL.keyPassword}") private String keyPassword; @Value("${httpClientUri}") private String url; public static final String GET = "GET"; public static final String POST = "POST"; public static final String PUT = "PUT"; /** * RestTemplate訪問https請求 * * @param data * @param addHeader * @return */ public String transferRestTemplate(String path, String data, String httpMethod, Consumer<HttpHeaders> addHeader) { String body = null; try { KeyStore keyStore = KeyStore.getInstance(keyStoreType); ClassPathResource resource = new ClassPathResource(keyFile); InputStream inputStream = new FileInputStream(resource.getFile()); keyStore.load(inputStream,keyPassword.toCharArray()); SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(keyStore, TrustSelfSignedStrategy.INSTANCE).build(); // Allow TLSv1 protocol only SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslcontext); CloseableHttpClient httpclient = HttpClients.custom() .setSSLSocketFactory(socketFactory) .build(); HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpclient); RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory); HttpHeaders requestHeaders = new HttpHeaders(); addHeader.accept(requestHeaders); requestHeaders.setContentType(MediaType.APPLICATION_JSON); HttpEntity<String> httpEntity = new HttpEntity<>(data, requestHeaders); ResponseEntity<String> response = null; switch(httpMethod){ case HttpsUtil.GET : response = restTemplate.exchange(url+ path, HttpMethod.GET, httpEntity, String.class); break; case HttpsUtil.POST : response = restTemplate.exchange(url+ path, HttpMethod.POST, httpEntity, String.class); break; case HttpsUtil.PUT : response = restTemplate.exchange(url+ path, HttpMethod.PUT, httpEntity, String.class); break; default: logger.error("非法請求方式:", new IllegalStateException(httpMethod)); } if (Objects.nonNull(response)) { if (response.getStatusCode().is2xxSuccessful()) { body = response.getBody(); } logger.info("返回狀態碼: {}, 返回數據: {}", response.getStatusCodeValue(), body); }else { logger.info("response is null"); } }catch (Exception e) { logger.error("https請求錯誤:", e); } return body; } }
8.通過域名訪問失敗原因及解決辦法
- 域名未配置解析,去域名管理配置解析,10分鍾后通過ping 域名看是否顯示ip,顯示則解析成功!
- 域名未認證,去域名管理上傳個人信息進行域名實名!
- 域名已實名但未網站未備案,解決辦法
- 去進行網站實名,使用騰訊雲小程序認證進行icp備案即可!
- 可以通過域名訪問但必須加上自定義端口才行,不能使用8080或443等默認端口,否則提示連接已重置!
