在spring中配置項目運行的端口很簡單。
在application.properties中
server.port: 8080
這樣配置后,spring boot內嵌的tomcat服務器就是跑在8080端口啟動http服務。但是如果在配置中啟動https服務,用到的端口也是server.port。spring 不支持同時在配置中啟動http和https。
但是如果這樣配置,項目只能走http協議。如果想讓項目支持https協議,可以有兩種方法。
一:在配置中配置https的配置信息,http采用硬編碼的方式
二:用硬編碼的方式來寫https
用硬編碼的方式寫https有點麻煩,所以一般都采用第一種方式。
無論用哪種方式,想支持https,一定要生成一對秘鑰。用openssl生成證書:
openssl genrsa -out server.key 2048 //生成服務器端私鑰 openssl req -new -key server.key -out server.csr //生成服務端證書請求文件 注意生成過程中需要你輸入一些服務端信息
openssl x509 -req -sha256 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -out server.crt //使用CA證書生成服務端證書 關於sha256,默認使用的是sha1,在新版本的chrome中會被認為是不安全的,因為使用了過時的加密算法。
openssl pkcs12 -export -in server.crt -inkey server.key -out server.pkcs12 //打包服務端的資料為pkcs12格式(非必要,只是換一種格式存儲上一步生成的證書)
生成過程中,需要創建訪問密碼,請記錄下來。
keytool -importkeystore -srckeystore server.pkcs12 -destkeystore server.jks -srcstoretype pkcs12 //生成服務端的keystore(.jks文件, 非必要,Java程序通常使用該格式的證書)
生成過程中,需要創建訪問密碼,請記錄下來。 把ca證書放到keystore中(非必要)
keytool -importcert -keystore server.jks -file ca.crt
生成證書后,讓瀏覽器信任跟證書(ca.crt)。
打開瀏覽器的設置。找到設置信任證書的部分。導入證書。
准備工作完畢,看一下代碼
application.properties
server.port: 8092 server.ssl.key-store=/home/fzk/key/server.jks server.ssl.key-store-password=123456 //這個是在生成證書的時候設置的密碼
fzk.port:8091
fzk.port:8091是自定義的名。因為不可能同時出現兩個server.port
同時支持http還需要一個java類
HttpsConfiguration.java (名字自己隨便起)
import org.apache.catalina.connector.Connector; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class HttpsConfiguration { @Value("${fzk.port}") private int port; @Bean public EmbeddedServletContainerFactory servletContainer() { TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory(); tomcat.addAdditionalTomcatConnectors(createHttpConnector()); return tomcat; } private Connector createHttpConnector() { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); connector.setScheme("http"); connector.setPort(port); connector.setSecure(false); return connector; } }
@Configuration是spring的注解,表示這是一個配置。@Value("${fzk.port}")找到配置文件中的fzk.port賦值給int類型的port。還可以寫成下面這樣:
@Configuration(prefix = "fzk") public class HttpsConfiguration { private int port; public void setPort(int port){ this.port = port; } public int getPort(){ return port; } }
此時類中的屬性名和配置文件中的名一定要對應上。
這樣就可以讓項目同時支持http和https了。
上面說了還有另外一種方法,采用硬編碼https的請求的方式。
配置文件中可以不用寫服務端口號,直接看java類
@Configuration public class HttpsConfiguration { @Bean public EmbeddedServletContainerCustomizer containerCustomizer() { return new EmbeddedServletContainerCustomizer() { @Override public void customize(ConfigurableEmbeddedServletContainer container) { Ssl ssl = new Ssl(); // Server.jks中包含服務器私鑰和證書 ssl.setKeyStore("/home/fzk/key/server.jks"); ssl.setKeyStorePassword("123456"); container.setSsl(ssl); container.setPort(8092); } }; } @Bean public EmbeddedServletContainerFactory servletContainerFactory() { TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory() { @Override protected void postProcessContext(Context context) { SecurityConstraint securityConstraint = new SecurityConstraint(); securityConstraint.setUserConstraint("CONFIDENTIAL"); SecurityCollection collection = new SecurityCollection(); collection.addPattern("/*"); securityConstraint.addCollection(collection); context.addConstraint(securityConstraint); } }; factory.addAdditionalTomcatConnectors(createHttpConnector()); return factory; } private Connector createHttpConnector() { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); connector.setScheme("http"); connector.setSecure(false); connector.setPort(8093); connector.setRedirectPort(8092); return connector; }
}
第一個bean的部分是使端口8092的https可以訪問。下面的部分是讓端口8093的http重定向到8092。