SpringBoot使用jetty和tomcat还有undertow以及ssl配置支持https请求

  • Post author:
  • Post category:其他


一般使用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

myw


也还有其他的一些配置


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

记录了,将来或许有机会用到。



版权声明:本文为myyhtw原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。