一般使用SpringBoot开发应用程序都是使用的tomcat 稍微注意点性能就使用undertow,配置支持https请求常用nginx来做代理,直接用SpringBoot配置还是很少的,八成用不到,就怕需要用到的时候又不能及时弄出来,于是记录一下。
使用的SpringBoot版本
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
直接使用tomcat的话 默认就好
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- spring-boot-starter-web 包含了这个的-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
使用jetty
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
使用undertow
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
在常用的端口这种配置是一样的,根据各自的不同也有不同的配置,比如吞吐量等,直接不配置使用默认配置就好,需要调优再根据具体的需求来选择。
server.port=8080
https请求配置
application.properties配置 三者一样 端口443 ssl证书参考阿里的证书
server.port=443
server.ssl.key-store=classpath:12345678_develop.mayiwu-example.com.pfx
server.ssl.key-store-password=12345678
tomcat
方式一 不推荐SslConfig.java
package boot.example.ssl.config;
import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SslConfig {
/**
* http 转 https
* 据说有坑,用这种方式将http重定向到https post方式会丢失请求参数,应该是导入的包出错的原因导致的,目前没有遇到,也没有详细测试
*/
@Bean
public Connector connector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
// 监听的http端口
connector.setPort(80);
connector.setSecure(false);
// 监听到http端口后跳转的https端口
connector.setRedirectPort(443);
return connector;
}
/**
* 拦截所有的请求
*/
@Bean
public TomcatServletWebServerFactory tomcatServletWebServerFactory(Connector connector) {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
@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);
}
};
//TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
tomcat.addAdditionalTomcatConnectors(connector);
return tomcat;
}
}
方式二
package boot.example.ssl.config;
import org.apache.catalina.connector.Connector;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
*
* 建议使用这种方式
*
*/
@Configuration
public class Ssl2Config {
@Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
tomcat.addAdditionalTomcatConnectors(createStandardConnector()); // 添加http
return tomcat;
}
// 配置http 只需要设置port不设置重定向,那么http https都可以访问
private Connector createStandardConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setPort(80);
return connector;
}
}
jetty
HttpToHttpsJettyConfig.java
package boot.example.ssl.config;
import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.util.security.Constraint;
import org.eclipse.jetty.webapp.AbstractConfiguration;
import org.eclipse.jetty.webapp.WebAppContext;
public class HttpToHttpsJettyConfig extends AbstractConfiguration {
@Override
public void configure(WebAppContext context) throws Exception {
Constraint constraint = new Constraint();
constraint.setDataConstraint(Constraint.DC_CONFIDENTIAL);
ConstraintMapping mapping = new ConstraintMapping();
mapping.setPathSpec("/*");
mapping.setConstraint(constraint);
ConstraintSecurityHandler handler = new ConstraintSecurityHandler();
handler.addConstraintMapping(mapping);
context.setSecurityHandler(handler);
}
}
WebServerFactoryCustomizerConfig.java
package boot.example.ssl.config;
import java.util.Collections;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.ServerConnector;
import org.springframework.boot.web.embedded.jetty.ConfigurableJettyWebServerFactory;
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WebServerFactoryCustomizerConfig implements WebServerFactoryCustomizer<ConfigurableJettyWebServerFactory>{
@Override
public void customize(ConfigurableJettyWebServerFactory factory) {
//这段代码将会使得http转https 如果注释掉,那么访问http将会访问80端口,https将会访问443端口,都是默认端口,就不会重定向到443端口
((JettyServletWebServerFactory)factory).setConfigurations(Collections.singleton(new HttpToHttpsJettyConfig()));
factory.addServerCustomizers(
server -> {
// https 443端口与配置文件里的端口保持一致
HttpConfiguration httpConfiguration = new HttpConfiguration();
httpConfiguration.setSecurePort(443);
httpConfiguration.setSecureScheme("https");
/**
* 一下端口配置了http转https都会转到443
*
*/
// http 80端口
ServerConnector connector = new ServerConnector(server);
connector.addConnectionFactory(new HttpConnectionFactory(httpConfiguration));
connector.setPort(80);
server.addConnector(connector);
//若是继续 还可以使用http 其他端口
ServerConnector connector2 = new ServerConnector(server);
connector2.addConnectionFactory(new HttpConnectionFactory(httpConfiguration));
connector2.setPort(8182);
server.addConnector(connector2);
}
);
}
}
undertow
package boot.example.ssl.config;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import io.undertow.Undertow;
import io.undertow.UndertowOptions;
import io.undertow.servlet.api.SecurityConstraint;
import io.undertow.servlet.api.SecurityInfo;
import io.undertow.servlet.api.TransportGuaranteeType;
import io.undertow.servlet.api.WebResourceCollection;
@Configuration
public class SslConfig {
/**
* 采用Undertow作为服务器。
* Undertow是一个用java编写的、灵活的、高性能的Web服务器,提供基于NIO的阻塞和非阻塞API,特点:
* 非常轻量级,Undertow核心瓶子在1Mb以下。它在运行时也是轻量级的,有一个简单的嵌入式服务器使用少于4Mb的堆空间。
* 支持HTTP升级,允许多个协议通过HTTP端口进行多路复用。
* 提供对Web套接字的全面支持,包括JSR-356支持。
* 提供对Servlet 3.1的支持,包括对嵌入式servlet的支持。还可以在同一部署中混合Servlet和本机Undertow非阻塞处理程序。
* 可以嵌入在应用程序中或独立运行,只需几行代码。
* 通过将处理程序链接在一起来配置Undertow服务器。它可以对各种功能进行配置,方便灵活。
*/
@Bean
public ServletWebServerFactory undertowFactory() {
UndertowServletWebServerFactory undertowFactory = new UndertowServletWebServerFactory();
undertowFactory.addBuilderCustomizers((Undertow.Builder builder) -> {
builder.addHttpListener(80, "0.0.0.0");
// 开启HTTP2
builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true);
});
undertowFactory.addBuilderCustomizers((Undertow.Builder builder) -> {
builder.addHttpListener(8088, "0.0.0.0");
// 开启HTTP2
builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true);
});
undertowFactory.addDeploymentInfoCustomizers(deploymentInfo -> {
// 开启HTTP自动跳转至HTTPS 注释后各自访问各自的
deploymentInfo.addSecurityConstraint(new SecurityConstraint()
.addWebResourceCollection(new WebResourceCollection().addUrlPattern("/*"))
.setTransportGuaranteeType(TransportGuaranteeType.CONFIDENTIAL)
.setEmptyRoleSemantic(SecurityInfo.EmptyRoleSemantic.PERMIT))
.setConfidentialPortManager(exchange -> 443);
});
return undertowFactory;
}
}
如果要开启http2 那么还需要在配置文件application.properties
server.http2.enabled=true
记录了,将来或许有机会用到。