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

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

  •  
  •   rizon · 72 天前 · 1983 次点击
    这是一个创建于 72 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    第 1 条附言  ·  71 天前

    已解决 和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
        1
    ywcjxf1515   72 天前 via iPad
    写一个过滤器,再加上一个包装类包装原有的 Request 对象,包装类重写拿到 url 的方法,使得 springmvc 发到相应的控制器方法?
        2
    ywcjxf1515   72 天前 via iPad
    要不在过滤器中做转发,使用 servlet 自带的转发?
        3
    leonme   72 天前 via Android
    拦截器
        4
    zgcwkj   72 天前
    用 shiro 不是更好?
        5
    HonoSV   72 天前
    shiro
        6
    Takamine   72 天前 via Android
    感觉拦截器就好,这个需求上 shiro 重了点。
        7
    rizon   71 天前
    @ywcjxf1515 #1
    @leonme #3
    @Takamine #6
    我也知道是拦截器,能有些具体的写法吗?不知道拦截器怎么才能修改 url 后重新发到对应的 controller
        8
    HuasLeung   71 天前 via Android
    拦截器或 AOP
        9
    HuasLeung   71 天前 via Android
    修改完 url 后 forward 转发对应 controller
        10
    honeycomb   71 天前 via Android
    @rizon 拦截器,或者 AOP 也可以达到类似的效果(在切面方法里把 request 找出来)。

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