【java笔记】记一次spring项目中重定向请求路径

11 篇文章 0 订阅
背景
  • 最近项目部署遇到这样一个问题:paas平台部署项目,健康检查接口固定路径为:/actuator/health,但该项目为每个请求路径加上全局的前缀,如:/api/actuator/health,所以paas平台规范不通过导致部署失败,可能很多人会想到,直接去掉全局/api 即可,但是否想过该项目很多前端页面、第三方平台已经都对接了该项目的接口,如去掉全局前缀,那么势必需要所有调用链头部请求也做修改,时间、成本都比较大,所以是否有一种方式请求的原始路径保持不变,重定向到新路径。
修改过程
  • 先去掉 全局前缀 application.yaml文件中server.servlet.context-path = /api ,
  • 方式一
    编写一个配置类,重新新增前缀/api,这样就可以指定不同的类或者路径下不同的前缀。
@Configuration
public class MyWebMvcConfigurationSupport extends WebMvcConfigurationSupport {

    @Bean
    public RequestMappingHandlerMapping requestMappingHandlerMapping() {
        return new MyCustomRequestMappingHandlerMapping();
    }

    private class MyCustomRequestMappingHandlerMapping extends RequestMappingHandlerMapping {

        private final static String PREFIX = "com.xx";

        private final static String EXCLUDE_CLASS = "com.xx.xxx.controller.HealthController";


        public MyCustomRequestMappingHandlerMapping() {
            super();
        }

        @Override
        protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) {
            Class<?> beanType = method.getDeclaringClass();
            //排除健康检查类
            if (!Objects.equals(beanType.getName(), EXCLUDE_CLASS) && beanType.getName().startsWith(PREFIX )) {
                RestController myRestAnnotation = beanType.getAnnotation(RestController.class);
                if (myRestAnnotation != null) {
                    PatternsRequestCondition oldPattern = mapping.getPatternsCondition();
                    PatternsRequestCondition apiPattern =  new PatternsRequestCondition("/api/");
                    //合并旧的url和新的
                    PatternsRequestCondition updatedFinalPattern = apiPattern.combine(oldPattern);
                    mapping = new RequestMappingInfo(
                            mapping.getName(),
                            updatedFinalPattern,
                            mapping.getMethodsCondition(),
                            mapping.getParamsCondition(),
                            mapping.getHeadersCondition(),
                            mapping.getConsumesCondition(),
                            mapping.getProducesCondition(),
                            mapping.getCustomCondition()
                    );
                }
            }
            super.registerHandlerMethod(handler, method, mapping);
        }
    }
}
  • 方式二:编写一个MVC配置类
@Configuration
public class PluginConfig implements WebMvcConfigurer {

public static final String PREFIX = "/api";

@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
    configurer.addPathPrefix(PREFIX, c -> c.isAnnotationPresent(RestController.class));
}
  • 方式三:编写一个过滤器重定向
@Order(0)
@Component
public class UrlFilter extends OncePerRequestFilter {

    /**
     *
     * 排除api关键字
     * @param request
     * @param response
     * @param filterChain
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
          String path = request.getRequestURI();
            path = "/api/"+ path
            request.getRequestDispatcher(path).forward(request, response);
     
    }
}

最后附一张过滤器、拦截器、servlet请求顺序的关系图,以上案例,不能使用拦截器,因为需要在经过servlet容器之前做定向处理。
请求过程:请求->Listener->ServletContainer->Filter->Servlet->Interceptor->Controller
SpringBoot中可查看这三个类对Filter、Servlet、Listener进行操作ServletListenerRegistrationBean、FilterRegistrationBean、ServletRegistrationBean
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值