Java 用于重写URL的servlet筛选器

Java 用于重写URL的servlet筛选器,java,url-rewriting,servlet-filters,Java,Url Rewriting,Servlet Filters,我正在尝试从以下位置重写URL: localhost:8080/sendmail/newEmail.pdf?请求id=23456&emailAddress= 致: localhost:8080/sendmail/newEmail.pdf?请求\u id=23456 下面是筛选器类代码和映射。我怎样才能完成这项任务?(请给出一个例子,不胜感激) 过滤器映射: <filter> <filter-name>RequestFilter</filter-nam

我正在尝试从以下位置重写URL:

  • localhost:8080/sendmail/newEmail.pdf?请求id=23456&emailAddress=
致:

  • localhost:8080/sendmail/newEmail.pdf?请求\u 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>

我建议使用现有的实现,而不是自己编写

似乎有一个Java URL重写实现,即Tuckey的URLRewiteFilter

见:

这应该是你想要的,还有更多

或者,如果您在web容器前面使用apache,您可能需要查看
mod_rewrite
,它在apache上执行相同的操作


如果您真正需要的只是这一个简单的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());
    }
}

我理解重新发明轮子的不情愿,但我不相信有人会认为在servlet容器前面添加Apache只是为了重写URL比创建一个简单的过滤器和几行代码要好。@stepanian是的,那太过分了,这就是为什么我首先建议使用Java解决方案,并说如果前面已经有了apache(无论出于何种原因),mod_rewrite可能是一种替代方法。
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());
    }
}