摘要:import org.springframework.http.server.reactive.HttpHandler。(3) Springboot以Tomcat爲容器實現http重定向到https的兩種方式。

1 簡介

Spring WebFlux 是一個新興的技術, Spring 團隊把寶都壓在響應式 Reactive 上了,於是推出了全新的 Web 實現。本文不討論響應式編程,而是通過實例講解 Springboot WebFlux 如何把 http 重定向到 https

作爲餐前小喫,建議大家先喫以下 https 小菜,以幫助理解:

(1) Springboot整合https原來這麼簡單

(2) HTTPS之密鑰知識與密鑰工具Keytool和Keystore-Explorer

(3) Springboot以Tomcat爲容器實現http重定向到https的兩種方式

(4) Springboot以Jetty爲容器實現http重定向到https

(5) nginx開啓ssl並把http重定向到https的兩種方式

2 搭建WebFlux項目

引入 WebFlux 的依賴如下:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

實現 Controller ,與之前略有不同,返回值爲 Mono<T>

@RestController
public class HelloController {
    @GetMapping("/hello")
    public Mono<String> hello() {
        return Mono.just("Welcome to www.pkslow.com");
    }
}

配置文件與普通的 Springboot 項目沒什麼差別,配置了兩個端口,並配置 SSL 相關參數:

server.port=443
http.port=80

server.ssl.enabled=true
server.ssl.key-store-type=jks
server.ssl.key-store=classpath:localhost.jks
server.ssl.key-store-password=changeit
server.ssl.key-alias=localhost

3 重定向實現

主要做了兩件事:

(1)在有 https 的情況下,啓動另一個 http 服務,主要通過 NettyReactiveWebServerFactory 來生成一個 Web 服務。

(2)把 http 重定向到 https ,這裏做了路徑判斷,加了一個簡單的過濾函數。通過提供一個新的 HttpHandler 來實現重定向。

package com.pkslow.ssl.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.HttpHandler;
import reactor.core.publisher.Mono;
import javax.annotation.PostConstruct;
import java.net.URI;
import java.net.URISyntaxException;

@Configuration
public class HttpToHttpsConfig {

    @Value("${server.port}")
    private int httpsPort;

    @Value("${http.port}")
    private int httpPort;


    @Autowired
    private HttpHandler httpHandler;

    @PostConstruct
    public void startRedirectServer() {
        NettyReactiveWebServerFactory factory = new NettyReactiveWebServerFactory(httpPort);
        factory.getWebServer(
                (request, response) -> {
                    URI uri = request.getURI();
                    URI httpsUri;
                    try {
                        if (isNeedRedirect(uri.getPath())) {
                            httpsUri = new URI("https",
                                    uri.getUserInfo(),
                                    uri.getHost(),
                                    httpsPort,
                                    uri.getPath(),
                                    uri.getQuery(),
                                    uri.getFragment());
                            response.setStatusCode(HttpStatus.MOVED_PERMANENTLY);
                            response.getHeaders().setLocation(httpsUri);
                            return response.setComplete();
                        } else {
                            return httpHandler.handle(request, response);
                        }

                    } catch (URISyntaxException e) {
                        return Mono.error(e);
                    }
                }
        ).start();

    }

    private boolean isNeedRedirect(String path) {
        return !path.startsWith("/actuator");
    }
}

4 總結

本文詳細代碼可在 南瓜慢說 公衆號回覆< SpringbootSSLRedirectWebFlux >獲取。

歡迎訪問 南瓜慢說 www.pkslow.com 獲取更多精彩文章!

歡迎關注微信公衆號< 南瓜慢說 >,將持續爲你更新...

多讀書,多分享;多寫作,多整理。

相關文章