【Response重定向拦截器】

背景

线上项目在对于现有的链接要求使用SSL的https请求,在使用HttpServletResponse对象进行重定向时、重定向后的URI变成http导致部分业务受影响

解决方案

通过搜索引擎目前有三种解决方案

  1. HttpServletRequest转发 ,通过转发的方式地址栏不变;
  2. Nginxreturn 301 / rewrite 两种配置选其一;
  3. HttpServletResponseWrapper 配合过滤器使用sendRedirect方法完成对重定向的URI的一个修改

这里采用第三种方法实现对URI的修改

实现步骤

编写URI重写逻辑


public class RedirectResponseWrapper extends HttpServletResponseWrapper {

    private final HttpServletRequest request;

    private final String BASEURL = "https://baidu.com";

    public RedirectResponseWrapper(final HttpServletRequest inRequest,
                                   final HttpServletResponse response) {
        super(response);
        this.request = inRequest;
    }

    @Override
    public void sendRedirect(final String pLocation) throws IOException {
        System.out.println("原始请求: "+request.getRequestURL());
        if (StringUtils.isEmpty(pLocation)) {
            super.sendRedirect(pLocation);
            return;
        }

        //重定向的路径
        String redirectPath = null;

        //判断是否是https请求是则放行
        try {
            final URI uri = new URI(pLocation);
            System.out.println("重定向请求: "+pLocation);
            redirectPath = uri.getPath();
            if (uri.getScheme() != null && "https".equals(uri.getScheme())) {
                super.sendRedirect(pLocation);
                return;
            }
        } catch (URISyntaxException ex) {
            super.sendRedirect(pLocation);
        }

        // !!! FIX Scheme 获取原始请求的信息!!!

        //Returns the name of the scheme used to make this request, for example, http, https, or ftp.

        String scheme = request.getScheme();

        //Returns the host name of the server to which the request was sent.

        String serverName = request.getServerName();

        //Returns the port number to which the request was sent.

        int port = request.getServerPort();

        //
        String contextPath = request.getContextPath();

        //原始请求的路径
        String servletPath = request.getServletPath();

        //原始请求的参数
        String queryString = request.getQueryString();


        StringBuilder sbd = new StringBuilder();
        // 获取基础URL

        if(port != 80 && port != 443) {
            sbd.append(":").append(port);
        }

        if(redirectPath != null) {
            sbd.append(redirectPath);
        }



        if(queryString != null) {
            sbd.append("?");
            sbd.append(queryString);
        }
        System.out.println("https请求: "+sbd.toString());
        super.sendRedirect(sbd.toString());
    }
}

编写过滤器

public class AbsoluteSendRedirectFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
    throws ServletException, IOException {
        RedirectResponseWrapper redirectResponseWrapper = new RedirectResponseWrapper(request, response);
        filterChain.doFilter(request, redirectResponseWrapper);
    }
}

注册过滤器

    @Bean
    public FilterRegistrationBean MyFilterRegistration() {

        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new AbsoluteSendRedirectFilter());
        registration.addUrlPatterns("/*");
        registration.setName("redirectFilter");
        registration.setOrder(1);
        return registration;
    }

验证跳转

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值