在tomcat的filter中如何修改重定向Response中的目的URL

qgw_2000 2010-05-15 09:58:17
最近写一个tomcat的filter,此filter对所有的jsp/sevlet生产的html代码做一些处理。碰到一个需求,需要改写重定向Resonse(301/302)中的URL, 重定向Response由Servlet中直接调用HttpResponseServlet.sendRedirect产生。

对于正常的HTTP Response,我的filter可以通过HttpResponseServlet提供的方法修改Response的Header和Body。但对于301/302的Response却没有办法获取和修改重定向的目的URL。请各位指教如何实现获取和修改重定向Response的目的URL。多谢。

目的URL对应Response Header中的location,如下所示。

HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: http://www.xxx.com/xxx
Content-Type: text/html;charset=UTF-8
Content-Length: 0
Date: Wed, 14 Apr 2010 09:36:30 GMT
...全文
1693 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
qgw_2000 2010-05-22
  • 打赏
  • 举报
回复
好几天没有更新,这里还是给一个完整的使用案例----防止CSRF攻击。

防止CSRF攻击的一个有效的做法是,确定向服务器发送的请求都是可以被验证是合法的。
通常做法是验证请求中是否包含某个正确的参数。这个参数是对每个session都是不一样的。

我现在的做法就是在用户登录成功后生成一个session唯一的key,然后在filter中处理请求返回的页面。
处理的步骤:
1.在所有的表单中添加一个hidden的input,其中的value就是上面生成的key。保证POST请求含有这个参数。
例如:
假设某个session的Key的值为“xsdfysaodjflaskdfas”
原来的表单;
<form name="xx" action="xxxx">
.... ....
</form>
处理后的表单:
<form name="xx" action="xxxx">
.... ....
<input type="hidden" name="token" value="xsdfysaodjflaskdfas">
</form>

2.对所有的<a>, <link>, <iframe>等标签中的链接加上参数。保证GET请求函数这个参数。
例如:
假设某个session的Key的值为“xsdfysaodjflaskdfas”
处理前的链接:
<a href="http://www.xxx.com/xxx">link</a>
处理后的链接:
<a href="http://www.xxx.com/xxx?token=xsdfysaodjflaskdfas">link</a>

问题出在原来系统中很多Servlet和JSP页面很多地方直接调用response.sendRedirect(location)。
在filter中没法处理这种Response,以达到在location中加入参数的目的。
客户端收到301/302重定向后,直接发送GET请求目的是location,此时这个请求就没有带有参数。

解决方案最好不要改动原有的系统代码,这也是使用filter实现的原因。

使用Wrapper然后重载sendRedirect方法可以解决问题,但需要改动原有系统中的Servlet和JSP页面来使用Wrapper过的Response对象。
shine333 2010-05-16
  • 打赏
  • 举报
回复
你过滤器的session和/yyy的session是同一个吧。
默认值!=固定值,你filter里面怎么算,servlet里面怎么“默认”好了

当然,具体方案还要看你实际需求
qgw_2000 2010-05-16
  • 打赏
  • 举报
回复
to shine333:
实际上param=something是随机生成的,每个session都不一样。
shine333 2010-05-16
  • 打赏
  • 举报
回复
干嘛搞那么复杂啊,只要/yyy这个servlet的param参数的默认值是something就可以了阿
qgw_2000 2010-05-16
  • 打赏
  • 举报
回复
to shine333:
不好意思,应该是我没有说清楚。

1. 需求是这样的,我通过filter处理所有的Response,分析Response页面的内容,对页面中的link加入特殊的参数。
比如对于页面中,
<a href="http://www.xxx.com/yyy">test</a>
经过filter处理过可能变成
<a href="http://www.xxx.com/yyy?param=something>test</a>
这样以后用户点击这个链接,发送的GET请求中就带有了这个参数(param=something)。


2. 原来的系统后台逻辑由Servlet实现,有很多Servlet会直接调用HttpSevletResponse.sendRedirect(location)函数进行页面跳转。
现在问题就来了,通过sendRedirect跳转过来的请求就不带这样的参数(param=something)。


3. 现在需要在尽量不修改原来系统代码的基础上实现这个需求
对你说的wrapper我是这样理解的:
i. 继承HttpServletResponse,重载sendRedirect方法,在重载后的方法中对location加上参数。

ii. 对原来系统中每个servlet进行如下类似处理,假设我的Wrapper类为MyHttpServletResponse:

原来的代码:
public MyServlet extents HttpServlet
{
protected void doGet(HttpServletRequest request, HttpServletResponse response)
{
... ...
resposne.sendRedirect("/goto.jsp");
... ...
}
}
改动后的代码:
public MyServlet extents HttpServlet
{
protected void doGet(HttpServletRequest request, HttpServletResponse response)
{
... ...
MyHttpServletResponse myResponse = new MyHttpServletResponse(response);
myResposne.sendRedirect("/goto.jsp");
... ...
}
}

不知以上描述是否清楚。
shine333 2010-05-16
  • 打赏
  • 举报
回复
没听懂啊,Servlet为什么要改写?
对于Servlet,wrapper和原本的没区别,而且filter-mapping可以配置只过滤特定的请求。

而且,说老实话,我也没看懂,为什么你有本文的需求
hnxxhc 2010-05-16
  • 打赏
  • 举报
回复
Wrapper应该可以解决
qgw_2000 2010-05-16
  • 打赏
  • 举报
回复
to shine333:
多谢。这样确实可以,不过原来系统的几百个Servlet都要进行改动,来使用wrap过的HttpServletResponse。
shine333 2010-05-16
  • 打赏
  • 举报
回复
你重写sendRedirect方法阿
public void sendRedirect(String location) throws IOException {
((HttpServletResponse) getResponse()).sendRedirect("mylocation"); 或者其他方法
}
qgw_2000 2010-05-16
  • 打赏
  • 举报
回复
to shine333:
对于正常的Response比如200,可以使用HttpServletResponseWrapper添加、修改header,但对于301/302仍然不起作用。并且没有方法获得重定向的目的URL。
shine333 2010-05-16
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 qgw_2000 的回复:]

多谢楼上两位。
to liang__:
我没法通过HttpServletResponseWrapper来获得和修改301/302 Response的目的URL。
to shine333:
我的需求是当Servlet中调用了response.sendRedirect("http://www.xxx.com/xxx"),然后在filter中获取并修改这个重定向的目的URL http://ww……
[/Quote]

使用Wrapper
qgw_2000 2010-05-16
  • 打赏
  • 举报
回复
to japt88_115656292:
.getRealPath是返回virtual path对应在本地文件系统上的路径,比如/index.jsp对应于/home/xxx/public_html/index.jsp等。
japt88_115656292 2010-05-16
  • 打赏
  • 举报
回复
.getRealPaht(); 然后判断吧
qgw_2000 2010-05-16
  • 打赏
  • 举报
回复
多谢楼上两位。
to liang__:
我没法通过HttpServletResponseWrapper来获得和修改301/302 Response的目的URL。
to shine333:
我的需求是当Servlet中调用了response.sendRedirect("http://www.xxx.com/xxx"),然后在filter中获取并修改这个重定向的目的URL http://www.xxx.com/xxx
shine333 2010-05-15
  • 打赏
  • 举报
回复
sendRedirect自动会生成这样的报文

if (需要重定向) {
response.sendRedirect("http://www.xxx.com/xxx");
return;
}

chain.doFilter(request,response);
liang__ 2010-05-15
  • 打赏
  • 举报
回复
httpservletresponsewrapper 应该可以吧。

81,092

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧