servlet 过滤器重写 URL
Posted
技术标签:
【中文标题】servlet 过滤器重写 URL【英文标题】:servlet filter to rewrite URL 【发布时间】:2013-03-16 22:03:57 【问题描述】:我正在尝试从以下位置重写 URL:
localhost:8080/sendEmail/newEmail.pdf?request_id=23456&emailAddress=
收件人:
localhost:8080/sendEmail/newEmail.pdf?request_id=23456
过滤器类代码和映射如下。我怎样才能完成这项任务? (非常感谢您提供示例答案)。
过滤器映射:
<filter>
<filter-name>RequestFilter</filter-name>
<filter-class>com.abc.ms.email.filter.RequestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>RequestFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
过滤代码:
public class RequestFilter implements Filter
private static final Pattern REWRITE_PATTERN = Pattern.compile("(^[1-9]\\d*)$");
public void doFilter(ServletRequest req, ServletResponse res, FilterChain fc) throws IOException, ServletException
HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper((HttpServletRequest)req);
String url = wrapper.getRequestURL().toString();
String number = url.substring(url.lastIndexOf("/")).replace("/", "");
Matcher m = REWRITE_PATTERN.matcher(number);
if (m.find())
RequestDispatcher dispatcher = wrapper.getRequestDispatcher("request?id=" + m.group(1));
dispatcher.forward(req, res);
else
fc.doFilter(wrapper, res);
【问题讨论】:
【参考方案1】:如果您真正需要的只是一个简单的 URL 清理,那么使用正则表达式或 URL 重写模块可能有点过头了。
一个完全简单的实现可能是这样的:
public class RequestFilter implements Filter
private static final String LOOK_FOR = "sendEmail/newEmail.pdf";
private static final String REMOVE = "&emailAddress=";
public void doFilter(ServletRequest req, ServletResponse res, FilterChain fc) throws IOException, ServletException
HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper((HttpServletRequest)req);
String original = wrapper.getRequestURL().toString();
if(original.contains(LOOK_FOR))
String filtered = StringUtils.substringBeforeLast(original, REMOVE);
RequestDispatcher dispatcher = wrapper.getRequestDispatcher(filtered);
dispatcher.forward(req, res);
else
fc.doFilter(wrapper, res);
使用org.springframework.mock.web.*
类可以轻松进行单元测试:
public class RequestFilterTest
private RequestFilter filter;
@Before
public void setUp()
filter = new RequestFilter();
@Test
public void testRedirect() throws IOException, ServletException
MockHttpServletRequest request = new MockHttpServletRequest("GET",
"/sendEmail/newEmail.pdf?request_id=23456&emailAddress=");
MockHttpServletResponse response = new MockHttpServletResponse();
MockFilterChain fc = new MockFilterChain();
filter.doFilter(request , response, fc);
Assert.assertEquals("http://localhost:80/sendEmail/newEmail.pdf?request_id=23456", response.getForwardedUrl());
【讨论】:
【参考方案2】:我建议使用现有的实现,而不是自己编写。
好像有一个Java URL重写实现,就是Tuckey的URLrewriteFilter。
见:http://tuckey.org/urlrewrite/
这应该可以满足您的需求,而且还可以做更多。
或者,如果您在 Web 容器前使用 apache,您可能需要查看
mod_rewrite
,在 apache 上也是如此。
http://httpd.apache.org/docs/current/mod/mod_rewrite.html
【讨论】:
我理解不情愿重新发明***,但我不敢相信有人会认为在 servlet 容器前添加 Apache 只是为了重写 URL 比创建一个简单的过滤器要好几行代码。 @stepanian 是的,这太过分了,这就是为什么我首先建议 Java 解决方案并说如果您前面已经有 apache(无论出于何种原因),mod_rewrite 可能是一种替代方法。跨度>以上是关于servlet 过滤器重写 URL的主要内容,如果未能解决你的问题,请参考以下文章
在 servlet 过滤器中,如何确定哪个 servlet 与 URL 匹配?