avatar

SpringBoot2 开启HTTP/2

操作流程

  1. 生成ssl证书
  2. 创建Spring Starter Project,并使用web和thymeleaf依赖
  3. 修改maven源,使用阿里服务器
  4. 使用undertow替换tomcat
  5. 修改项目配置,启用ssl和http2
  6. 创建自定义配置类,将http请求重定向到https
  7. 验证网站是否使用http/2

关键代码如下:

pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.pwfu</groupId>
<artifactId>demo</artifactId>
<version>0.0.1</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>

<properties>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<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>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>central</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<layout>default</layout>
<!-- 是否开启发布版构件下载 -->
<releases>
<enabled>true</enabled>
</releases>
<!-- 是否开启快照版构件下载 -->
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>

com.pwfu.demo.config.SSLConfig.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.pwfu.demo.config;

import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
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 {
@Bean
public ServletWebServerFactory undertowFactory() {
UndertowServletWebServerFactory undertowFactory = new UndertowServletWebServerFactory();
undertowFactory.addBuilderCustomizers((Undertow.Builder builder) -> {
builder.addHttpListener(8888, "0.0.0.0");
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;
}
}

com.pwfu.demo.web.controller.IndexController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.pwfu.demo.web.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class IndexController {
@RequestMapping(value="/")
public String index() {
return "{\"a\":1}";
}
}

resources/application.properties

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
server.servlet.context-path=/

server.port=443
server.undertow.uri-encoding=UTF-8
server.http2.enabled=true

spring.thymeleaf.cache=false

spring.devtools.restart.enabled=true

spring.devtools.restart.additional-paths=src/main/java

spring.messages.basename=i18n/messages
spring.messages.encoding=UTF-8

#logging.level.com.bonc = info

spring.mvc.view.prefix=/templates/
spring.mvc.view.suffix=.html

server.ssl.key-store = classpath:keystore.p12
server.ssl.key-store-password=
server.ssl.keyStoreType= PKCS12
server.ssl.keyAlias: ssl

生成ssl证书

.crt证书参见之前的文章
.p12证书需要用openssl从.crt证书和.key文件转换

openssl pkcs12 -export -out keystore.p12 -inkey ssl.key -in ssl.crt -name “ssl”

验证网站是否使用http/2

打开chrome浏览器的控制台输入performance.getEntriesByType('navigation')[0],如果打印的信息中nextHopProtocol值为h2,说明启用成功.

文章作者: pengweifu
文章链接: https://www.pengwf.com/2020/04/29/other/springboot2-http2/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 麦子的博客
打赏
  • 微信
    微信
  • 支付宝
    支付宝

评论