如何在Java中使用Servlet过滤器来更改传入的Servlet请求网址?


186

如何使用Servlet过滤器来更改来自的传入Servlet请求网址

http://nm-java.appspot.com/Check_License/Dir_My_App/Dir_ABC/My_Obj_123

http://nm-java.appspot.com/Check_License?Contact_Id=My_Obj_123


更新:根据BalusC的以下步骤,我想到了以下代码:

public class UrlRewriteFilter implements Filter {

    @Override
    public void init(FilterConfig config) throws ServletException {
        //
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;
        String requestURI = request.getRequestURI();

        if (requestURI.startsWith("/Check_License/Dir_My_App/")) {
            String toReplace = requestURI.substring(requestURI.indexOf("/Dir_My_App"), requestURI.lastIndexOf("/") + 1);
            String newURI = requestURI.replace(toReplace, "?Contact_Id=");
            req.getRequestDispatcher(newURI).forward(req, res);
        } else {
            chain.doFilter(req, res);
        }
    }

    @Override
    public void destroy() {
        //
    }
}

相关条目web.xml如下所示:

<filter>
    <filter-name>urlRewriteFilter</filter-name>
    <filter-class>com.example.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>urlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

我尝试了服务器端和客户端重定向,均获得了预期的结果。它成功了,谢谢BalusC!



您正在使用哪个版本的servlet规范?您转发请求的方式会随不同版本而变化。
罗曼·希波

看到这篇文章,它也有一个过滤器,它
可以满足

请注意,如果原始URL包含参数,即nm-java.appspot.com/Check_License/Dir_My_App/Dir_ABC/My_Obj_123?** param1 = A&param2 = B **,那么这些参数也将转发到下一个servlet / jsp。我没有找到摆脱或替换原始参数的方法(仅通过使用HttpServletRequestWrapper)。有什么想法吗?更新:看来http://ocpsoft.org/opensource/how-to-safe-add-modify-servlet-request-parameter-values/解决了这个问题。
罗布敦2012年

谢谢,我正在寻找有关URL重写和加密的示例。
阿迪亚亚达(Aditya Yada)

Answers:


281
  1. 实施javax.servlet.Filter
  2. doFilter()方法中,将传入的内容强制转换ServletRequestHttpServletRequest
  3. HttpServletRequest#getRequestURI()抢的路径。
  4. 使用简单的java.lang.String方法,如substring()split()concat()等提取感兴趣的部分,构成了新的路径。
  5. 使用或ServletRequest#getRequestDispatcher()然后RequestDispatcher#forward()将请求/响应转发到新的URL(服务器端重定向,不反映在浏览器地址栏中),将传入的内容强制转换ServletResponseHttpServletResponse然后HttpServletResponse#sendRedirect()将响应重定向到新的URL(客户端重定向,反映在浏览器地址栏)。
  6. 注册过滤器web.xmlurl-pattern/*/Check_License/*根据上下文路径上,或者如果你是在Servlet的3.0已经使用了@WebFilter注解为代替。

不要忘记在代码中添加检查,如果需要更改URL ,如果不需要,则只需调用FilterChain#doFilter(),否则它将在无限循环中调用自身。

另外,您也可以只使用现有的第三方API为您完成所有工作,例如Tuckey的UrlRewriteFilter,可以像使用Apache的方式进行配置mod_rewrite


1
是否有任何doFilter()示例代码可以满足上述要求?谢谢。
弗兰克(Frank)2010年

20
您到底停留在哪一步?我的回答几乎是写代码本身。您是否还注意到,蓝色的代码引用实际上是指向Javadocs的链接,该链接详细描述了类/方法的行为?在任何方式,你可以找到这里这里良好的JSP / Servlet的教程,特别是一个了解过滤器。
BalusC

1
我认为这是正确的,但是如果过滤器是链中的第一个过滤器RequestDispatcher#forward()并被执行,则其余过滤器将不会执行。那么,作为servlet来做,这将不是更好的方法吗?
lucasvc 2014年

2
@datakey:只需重新排列顺序或添加<dispatcher>FORWARD</dispatcher>到过滤器映射即可。
BalusC 2014年

1
@ JimJim2000:只需重新排列顺序或添加<dispatcher>FORWARD</dispatcher>到过滤器映射即可。
BalusC


7

一个简单的JSF Url Prettyfier过滤器,基于BalusC的答案步骤。过滤器将所有从/ ui路径开始的请求(假设您已存储所有xhtml文件)转发到同一路径,但添加了xhtml后缀。

public class UrlPrettyfierFilter implements Filter {

    private static final String JSF_VIEW_ROOT_PATH = "/ui";

    private static final String JSF_VIEW_SUFFIX = ".xhtml";

    @Override
    public void destroy() {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpServletRequest = ((HttpServletRequest) request);
        String requestURI = httpServletRequest.getRequestURI();
        //Only process the paths starting with /ui, so as other requests get unprocessed. 
        //You can register the filter itself for /ui/* only, too
        if (requestURI.startsWith(JSF_VIEW_ROOT_PATH) 
                && !requestURI.contains(JSF_VIEW_SUFFIX)) {
            request.getRequestDispatcher(requestURI.concat(JSF_VIEW_SUFFIX))
                .forward(request,response);
        } else {
            chain.doFilter(httpServletRequest, response);
        }
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {

    }

}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.