java - servlet 过滤器重写 URL

标签 java url-rewriting servlet-filters

我正在尝试从以下位置重写 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);
        }
    }
}

最佳答案

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

关于java - servlet 过滤器重写 URL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15648437/

相关文章:

jsf - Servlet 过滤器和 Servlet 上下文监听器有什么区别?

.htaccess - 使用 Mod_Rewrite 去除扩展

asp.net - ASP.Net 使用什么 URL 重写器?

html - 使用多部分/表单数据时如何从请求中获取字符串参数?

authentication - Spring-security/Grails 应用程序 - 未调用自定义 WebSecurity 配置

asp.net - IIS 的 URL 重写规则替换每个页面中的文件夹路径

java - 如何跳过表格行

java - 如何将数字转换为ascii值或字符并存储在字符串数组中

java - 为 Java 客户端设置 SFTP 服务器以仅允许使用公钥下载

java - 为什么 Hibernate 生成一个连接错误列的查询?