springcloud gateway設置context-path的操作

今天說一下遇到的問題,關於 springcloud gateway 設置 context-path 的問題。

1.使用場景

由於沒有申請二級域名,網關使用的地址是 xxx.com/gateway/ 用nginx轉發的時候 /gateway/ 也被用來尋址。

gateway 沒辦法設置 context-path ,針對我這個場景有3個解決方案。

2.解決方案

2.1 增加本地路由(有一個網址指向自己,這裡就是 /gateway)

spring:
  cloud:
    gateway:
      routes:
      # 網關本身沒有contextPath,通過自己轉發自己,達到能處理contextPath
      - id: self
        uri: http://localhost:${server.port}
        predicates:
        - Path=/${spring.application.name}/**
        filters:
        - StripPrefix=1
        order: -11000

這種方式會丟失請求,暫時沒考慮原因,就pass瞭。

2.2 增加過濾器,改寫路徑

ApiFilter.java

package com.yiche.ballast.filter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.WebFilter;
import reactor.core.publisher.Mono; 
 
@Configuration
public class ApiFilter {
    @Value("${spring.cloud.gateway.api-prefix:/gateway}")
    private String prefix; 
    @Bean
    @Order(-1)
    public WebFilter apiPrefixFilter() {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
 
            String path = request.getURI().getRawPath();
            if (!path.contains(prefix)) {
                ServerHttpResponse response = exchange.getResponse();
                response.setStatusCode(HttpStatus.BAD_GATEWAY);
 
                DataBuffer buffer = response
                        .bufferFactory()
                        .wrap(HttpStatus.BAD_GATEWAY.getReasonPhrase().getBytes());
                return response.writeWith(Mono.just(buffer));
            }
            String newPath = path.replaceFirst(prefix, "");
            ServerHttpRequest newRequest = request.mutate().path(newPath).build();
 
            return chain.filter(exchange.mutate().request(newRequest).build());
        };
    }
}

這樣/gateway 請求進來之後,轉發到routers 的時候會把 /gateway去掉,缺點是每個請求進來都需要對路徑處理一次。

能配置的盡量不寫代碼。

2.3 修改配置,在所有的router路徑前加前綴(這裡就是都加上 /gateway)

spring:
    cloud:
        gateway:
            routes:
            - id: api-route
              filters:
                - StripPrefix=1
              predicates:
                - name: Path
                  args[pattern]: /gateway/api/**
              uri: lb://xxx-api

偷懶的做法,路由多的時候也挺難受。

現在路由不多,選擇瞭第三種方式。看各自的場景選擇吧。

springcloud 的gateway踩坑

添加瞭路由規則的配置以後,SpringCloud無法正常啟動,啟動的時候報錯

1、配置文件中開啟debug=true模式

錯誤信息顯示缺少javax.validation.ValidatorException類;

2、在pom文件中添加hibernate-validator(以及所有相關依賴)

3、結果仍舊報錯,此時錯誤信息:

不能為空,之前是配置在yml文件中,後來換成瞭properties,問題就解決瞭;

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。

推薦閱讀: