V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
rizon
V2EX  ›  程序员

spring boot 有没有办法全局拦截 url 进行截断处理

  •  
  •   rizon ·
    othorizon · 2019-09-27 11:52:50 +08:00 · 5089 次点击
    这是一个创建于 1889 天前的主题,其中的信息可能已经有所发展或是发生改变。

    请求方会在 url 后面加上一个特殊的路径走网关去处理这个地址。
    但是现在有个服务会直接接收请求不走网关,也不能加 nginx 处理 url。 那么 Spring 有办法去全局处理 url 吗?把地址截断。

    请求地址: http://server/path/tag 真实的地址: http://server/path

    不讨论为什么会出现这种场景,为什么不合理这些东西。 只是单纯的想知道技术上怎么去全局重写 url 地址。

    第 1 条附言  ·  2019-09-27 19:52:30 +08:00

    已解决 和21楼方案一样,写了filter去重写。 不过有个细节是 getRequestDispatcher 的参数是一个相对路径,所以如果服务用context 的话,这里要调整一下,可以使用 httpRequest.getServletPath() 不包含contextPath

     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest httpRequest = (HttpServletRequest) request;
            //获取不包含contextPath的路径,因为重定向是使用的相对路径
            String servletPath = httpRequest.getServletPath();
            Matcher matcher = PATTERN.matcher(servletPath);
            if (matcher.matches()) {
                String newPath = matcher.group(1);
                log.info("rewrite relative request uri,from:{},to:{}", servletPath, newPath);
                request.getRequestDispatcher(newPath).forward(request, response);
            } else {
                chain.doFilter(request, response);
            }
        }
    
    24 条回复    2019-09-28 10:09:27 +08:00
    ywcjxf1515
        1
    ywcjxf1515  
       2019-09-27 12:14:37 +08:00 via iPad
    写一个过滤器,再加上一个包装类包装原有的 Request 对象,包装类重写拿到 url 的方法,使得 springmvc 发到相应的控制器方法?
    ywcjxf1515
        2
    ywcjxf1515  
       2019-09-27 12:16:57 +08:00 via iPad
    要不在过滤器中做转发,使用 servlet 自带的转发?
    leonme
        3
    leonme  
       2019-09-27 12:17:19 +08:00 via Android
    拦截器
    zgcwkj
        4
    zgcwkj  
       2019-09-27 12:19:25 +08:00
    用 shiro 不是更好?
    HonoSV
        5
    HonoSV  
       2019-09-27 12:28:35 +08:00
    shiro
    Takamine
        6
    Takamine  
       2019-09-27 12:31:51 +08:00 via Android
    感觉拦截器就好,这个需求上 shiro 重了点。
    rizon
        7
    rizon  
    OP
       2019-09-27 14:24:32 +08:00
    @ywcjxf1515 #1
    @leonme #3
    @Takamine #6
    我也知道是拦截器,能有些具体的写法吗?不知道拦截器怎么才能修改 url 后重新发到对应的 controller
    HuasLeung
        8
    HuasLeung  
       2019-09-27 14:24:38 +08:00 via Android
    拦截器或 AOP
    HuasLeung
        9
    HuasLeung  
       2019-09-27 14:26:03 +08:00 via Android
    修改完 url 后 forward 转发对应 controller
    honeycomb
        10
    honeycomb  
       2019-09-27 14:29:33 +08:00 via Android
    @rizon 拦截器,或者 AOP 也可以达到类似的效果(在切面方法里把 request 找出来)。

    可以考虑先从 AOP 入手,这样可以完全不影响到现有代码(不想要了的时候,只要去掉 pointcut 注解),如果试了一下觉得 AOP 不满足需求的话再用拦截器不迟。
    sunsulei
        11
    sunsulei  
       2019-09-27 14:30:17 +08:00
    不一定好做. 因为 url 进去了. 肯定先被 servletDispacher 处理, 那会已经确定了具体的处理 controller 以及 method.
    feiyizhan
        12
    feiyizhan  
       2019-09-27 14:34:55 +08:00
    继承 HttpServletRequestWrapper,然后实现一个过滤器,在过滤器的 doFilter 方法里调用 chain.doFilter 方法时,传入自己实现的 request。
    LeeSeoung
        13
    LeeSeoung  
       2019-09-27 14:41:16 +08:00
    urlrewritefilter 有搜到这个包 看下能满足?
    tzh1247
        14
    tzh1247  
       2019-09-27 14:45:03 +08:00
    Jfinal 中的 Handler 有这个功能
    luozic
        15
    luozic  
       2019-09-27 14:54:14 +08:00
    拦截器 AOP 实际这种 niginx 转发或者网关处理更干净
    66beta
        16
    66beta  
       2019-09-27 15:02:28 +08:00 via Android
    JAVA 新手路过,spring 的卖点不就是切片吗?
    licoycn
        17
    licoycn  
       2019-09-27 15:04:32 +08:00
    拦截器,AOP
    iiicarus
        18
    iiicarus  
       2019-09-27 15:21:27 +08:00
    AOP 做,pointcut 拦截所有 controller,然后拿到 URL,过滤掉不需要的 URL,然后再进行一系列操作。前几天刚好完成了类似功能。http 日志详细记录。
    ywcjxf1515
        19
    ywcjxf1515  
       2019-09-27 15:22:41 +08:00
    测试过了,我说的两种方法都行。
    /qaz 对应的是 test()方法,想让 /qaz/test 调用 test()方法。不使用转发或者包装类,/qaz/test 不能调用 test()方法。
    aHR0cHM6Ly9pLmxvbGkubmV0LzIwMTkvMDkvMjcvOExmSDJ4NlVDRTM5YndlLnBuZw==
    aHR0cHM6Ly9pLmxvbGkubmV0LzIwMTkvMDkvMjcvNzNTZXhRMnFXSktFbm01LnBuZw==
    aHR0cHM6Ly9pLmxvbGkubmV0LzIwMTkvMDkvMjcvZGJOTWZZRXpybXk1S2pvLnBuZw==
    (utf-8,base64)
    @rizon
    aragakiyuii
        20
    aragakiyuii  
       2019-09-27 15:50:13 +08:00 via Android   ❤️ 1
    shiro 用 filter,springmvc 用 interceptor,spring 用 aop
    WUWENZE
        21
    WUWENZE  
       2019-09-27 15:59:38 +08:00
    rizon
        22
    rizon  
    OP
       2019-09-27 19:48:15 +08:00
    @WUWENZE #21 解决了 也是这个方案 写 filter
    rizon
        23
    rizon  
    OP
       2019-09-27 19:51:18 +08:00
    @WUWENZE #21 不过有个细节是 getRequestDispatcher 的参数是一个相对路径,所以如果服务用 context 的话,这里要调整一下,可以使用 httpRequest.getServletPath() 不包含 contextPath
    fox0001
        24
    fox0001  
       2019-09-28 10:09:27 +08:00 via Android
    我们项目集成了 urlrewritefilter,这种情况写个 rewrite 规则就可以了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3397 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 11:26 · PVG 19:26 · LAX 03:26 · JFK 06:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.