请求方会在 url 后面加上一个特殊的路径走网关去处理这个地址。
但是现在有个服务会直接接收请求不走网关,也不能加 nginx 处理 url。 那么 Spring 有办法去全局处理 url 吗?把地址截断。
请求地址: http://server/path/tag 真实的地址: http://server/path
不讨论为什么会出现这种场景,为什么不合理这些东西。 只是单纯的想知道技术上怎么去全局重写 url 地址。
已解决 和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); } }
1 ywcjxf1515 2019-09-27 12:14:37 +08:00 via iPad 写一个过滤器,再加上一个包装类包装原有的 Request 对象,包装类重写拿到 url 的方法,使得 springmvc 发到相应的控制器方法? |
2 ywcjxf1515 2019-09-27 12:16:57 +08:00 via iPad 要不在过滤器中做转发,使用 servlet 自带的转发? |
![]() | 3 leonme 2019-09-27 12:17:19 +08:00 via Android 拦截器 |
![]() | 4 zgcwkj 2019-09-27 12:19:25 +08:00 用 shiro 不是更好? |
![]() | 5 HonoSV 2019-09-27 12:28:35 +08:00 shiro |
![]() | 6 Takamine 2019-09-27 12:31:51 +08:00 via Android 感觉拦截器就好,这个需求上 shiro 重了点。 |
![]() | 7 rizon OP |
![]() | 8 BCy66drFCvk1Ou87 2019-09-27 14:24:38 +08:00 via Android 拦截器或 AOP |
![]() | 9 BCy66drFCvk1Ou87 2019-09-27 14:26:03 +08:00 via Android 修改完 url 后 forward 转发对应 controller |
10 honeycomb 2019-09-27 14:29:33 +08:00 via Android @rizon 拦截器,或者 AOP 也可以达到类似的效果(在切面方法里把 request 找出来)。 可以考虑先从 AOP 入手,这样可以完全不影响到现有代码(不想要了的时候,只要去掉 pointcut 注解),如果试了一下觉得 AOP 不满足需求的话再用拦截器不迟。 |
![]() | 11 lotmany 2019-09-27 14:30:17 +08:00 不一定好做. 因为 url 进去了. 肯定先被 servletDispacher 处理, 那会已经确定了具体的处理 controller 以及 method. |
12 feiyizhan 2019-09-27 14:34:55 +08:00 继承 HttpServletRequestWrapper,然后实现一个过滤器,在过滤器的 doFilter 方法里调用 chain.doFilter 方法时,传入自己实现的 request。 |
![]() | 13 LeeSeoung 2019-09-27 14:41:16 +08:00 urlrewritefilter 有搜到这个包 看下能满足? |
![]() | 14 tzh1247 2019-09-27 14:45:03 +08:00 Jfinal 中的 Handler 有这个功能 |
15 luozic 2019-09-27 14:54:14 +08:00 拦截器 AOP 实际这种 niginx 转发或者网关处理更干净 |
![]() | 16 66beta 2019-09-27 15:02:28 +08:00 via Android JAVA 新手路过,spring 的卖点不就是切片吗? |
![]() | 17 licoycn 2019-09-27 15:04:32 +08:00 拦截器,AOP |
![]() | 18 iiicarus 2019-09-27 15:21:27 +08:00 AOP 做,pointcut 拦截所有 controller,然后拿到 URL,过滤掉不需要的 URL,然后再进行一系列操作。前几天刚好完成了类似功能。http 日志详细记录。 |
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 |
![]() | 20 aragakiyuii 2019-09-27 15:50:13 +08:00 via Android ![]() shiro 用 filter,springmvc 用 interceptor,spring 用 aop |
21 WUWENZE 2019-09-27 15:59:38 +08:00 |
![]() | 23 rizon OP @WUWENZE #21 不过有个细节是 getRequestDispatcher 的参数是一个相对路径,所以如果服务用 context 的话,这里要调整一下,可以使用 httpRequest.getServletPath() 不包含 contextPath |
24 fox0001 2019-09-28 10:09:27 +08:00 via Android 我们项目集成了 urlrewritefilter,这种情况写个 rewrite 规则就可以了 |