美文网首页
Gateway 为什么设置 server.servlet.con

Gateway 为什么设置 server.servlet.con

作者: 综合楼 | 来源:发表于2023-02-23 11:17 被阅读0次

背景

Gateway服务pom.xml
<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
普通服务pom.xml
<dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
</dependency>
配置文件
server:
  servlet:
    context-path: /api
接口url: /test

Gateway服务:context-path失效

正常访问:/test
无法访问:/api/test

普通服务:context-path生效

无法访问:/test
正常访问:/api/test

原因: server.servlet.context-path是webmvc配置。

gateway用的是长连接,netty-webflux,zuul1.0用的就是同步webmvc。
非gateway子项目启动用的是webmvc,gateway启动用的是webflux
spring-boot-start-web和spring-boot-start-webflux相见分外眼红。
不能配置在同一pom.xml,或者不能在同一项目中出现。

解决方案:添加WebFilter

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.WebFilter;

@Configuration
public class ContextPathConfig {
 
    @Bean
    @ConditionalOnProperty("server.servlet.context-path")
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public WebFilter contextPathWebFilter(ServerProperties serverProperties){
        String contextPath = serverProperties.getServlet().getContextPath();
 
        return (serverWebExchange, webFilterChain) ->{
            ServerHttpRequest request = serverWebExchange.getRequest();
            String requestPath = request.getURI().getPath();
 
            if(requestPath.contains(contextPath)){
                String newPath = requestPath.replaceFirst(contextPath, "");
                ServerHttpRequest newRequest = request.mutate()
                                .path(newPath).build();
                return webFilterChain.filter(serverWebExchange.mutate()
                                .request(newRequest)
                                .build()
                );
            }else {
                throw new ResponseStatusException(HttpStatus.NOT_FOUND);
            }
        };
    }
}

相关文章

网友评论

      本文标题:Gateway 为什么设置 server.servlet.con

      本文链接:https://www.haomeiwen.com/subject/grwzkdtx.html