在Spring Boot中启用Http2.0

Posted 大扑棱蛾子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Spring Boot中启用Http2.0相关的知识,希望对你有一定的参考价值。

HTTP2.0特性

使用HTTP/2的几点注意事项

要使用HTTP/2需要注意以下几点

  1. 虽然HTTP/2没有明确要求必须使用TLS,但当前几乎所有浏览器均只支持 HTTP/2 Over TLS。所以在使用之前我们需要先制作一张证书。
  2. 如果您的项目中用的是tomcatjetty,它们并不能直接支持HTTP/2,但是undertow可以。具体可以参考Spring Boot的文档:https://docs.spring.io/spring-boot/docs/2.0.5.RELEASE/reference/htmlsingle/#howto-configure-http2
  3. 我们制作的证书是不被浏览器认可的,所以会有安全提示,不能用于生产环境

在本文的例子中使用的是undertow

制作证书

使用JDK自带的keytool,证书类型为:PKCS12

keytool -genkey -alias undertow -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -dname "CN=localhost, OU=localhost, O=localhost, L=Zhengzhou, ST=Henan, C=CN"
输入密钥库口令:
再次输入新口令:

执行时会要求输入证书口令,这里输入的是123456。执行完命令后会在执行的文件夹生成一个keystore.p12的文件。

keytool的详细用法: https://docs.oracle.com/javase/8/docs/technotes/tools/windows/keytool.html
常见的证书格式及其说明参考:http://www.cnblogs.com/xq1314/archive/2017/12/05/7987216.html

配置Web容器

spring boot默认使用的是tomcat,我们需要先将tomcat移除,然后换成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>

如果不移除tomcat依赖会一直以Tomcat作为容器启动。

然后将刚才生成的keystore.p12拷贝到src/main/resources下。然后在application.yml中配置服务器信息。

server:
  port: 8443 # 端口
  compression:
    enabled: true
  http2:
    enabled: true # 启用http2
  ssl:
    enabled: true
    key-store: classpath:keystore.p12 # 启用http2
    key-store-password: 123456 # 证书密码
    key-store-type: PKCS12 # 证书类型
    protocol: TLSv1.2 # 协议类型
    key-alias: undertow

这时如果启动服务器,是只支持https的。

@SpringBootApplication
public class RabbitmqProducerApplication implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> 

    public static void main(String[] args) 
        SpringApplication.run(RabbitmqProducerApplication.class, args);
    

    @Override
    public void customize(UndertowServletWebServerFactory factory) 
        factory.addBuilderCustomizers((UndertowBuilderCustomizer) builder -> 
            builder.addHttpListener(8080, "0.0.0.0");
        );
    

这里增加8080端口的监听,配置参考:

启动后可以看到控制台打印出如下信息:

INFO 4288 --- [           main] o.s.b.w.e.u.UndertowServletWebServer     : Undertow started on port(s) 8443 (https) 8080 (http) with context path ''

测试

增加一个测试控制器

@RestController
@RequestMapping("/log")
public class LogController 

    private Logger logger = LoggerFactory.getLogger(LogController.class);

    @GetMapping("/info")
    public String info() 
        logger.info("Info log");
        return "info";
    

访问:https://localhost:8443/log/info,观察控制台protocolh2,说明这次请求使用的是HTTP/2协议。

再次请求

观察两次请求的size,一次是236一次是69,这是因为HTTP/2的头部压缩技术。

访问:http://localhost:8080/log/info,观察控制台可以看到使用的仍然是HTTP/1.1协议

而且数据包要比HTTP/2的数据包大,并且无论刷新多少次,大小是不变的。

以上是关于在Spring Boot中启用Http2.0的主要内容,如果未能解决你的问题,请参考以下文章

带有 Java 11、HTTPS 和 HTTP 2.0 的 Spring Boot 2

Spring Boot 在使用 solrj 而不是 spring-boot-starter-data-solr 时会爆炸

如何在 Spring Boot 中使用 Spring Security 启用 CORS

Spring Boot 应用程序在 AWS 上的自动缩减

如何在 Spring Boot 和 Angular 中启用 CORS

如何在 Spring Boot 中启用 HTTP 响应缓存