请求方会在 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
sunsulei 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 1
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 规则就可以了
|