如何在Java中使用servlet过滤器来更改传入的servlet请求URL?

Fra*_*ank 179 java url servlets request servlet-filters

如何使用servlet过滤器来更改传入的servlet请求URL

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() {
        //
    }
}
Run Code Online (Sandbox Code Playgroud)

相关条目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>
Run Code Online (Sandbox Code Playgroud)

我尝试了服务器端和客户端重定向以及预期的结果.它起作用了,谢谢BalusC!

Bal*_*usC 272

  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.

  • 你究竟走到了什么阶段?我的回答几乎写了代码本身.您是否还注意到蓝色代码引用实际上是指向Javadocs的链接,它详细描述了类/方法行为?无论如何,你可以找到[这里](http://courses.coreservlets.com/Course-Materials/csajsp2.html)和[这里](http://courses.coreservlets.com/Course-Materials/msajsp. html)很好的JSP/Servlet教程,特别是[this](http://courses.coreservlets.com/Course-Materials/pdf/msajsp/05-Filters.pdf)一个关于过滤器的内容. (20认同)
  • @Kumar:只需按右上方的"提问"按钮. (2认同)
  • 我认为这是正确的,但如果过滤器是链中的第一个过滤器,并且执行了“RequestDispatcher#forward()”,则其余过滤器将不会被执行。那么,将其作为 servlet 执行此操作不是更好的方法吗? (2认同)
  • @datakey:只需重新排列顺序或添加`<dispatcher> FORWARD </ dispatcher>`来过滤映射. (2认同)
  • @BalusC 我们可以在不重定向或呼叫转发的情况下做到这一点吗? (2认同)

Pas*_*ent 21

您可以使用准备使用Url Rewrite Filter的规则如下:

<rule>
  <from>^/Check_License/Dir_My_App/Dir_ABC/My_Obj_([0-9]+)$</from>
  <to>/Check_License?Contact_Id=My_Obj_$1</to>
</rule>
Run Code Online (Sandbox Code Playgroud)

查看示例以获取更多...示例.


Xtr*_*ica 6

一个简单的基于BalusC回答步骤的JSF Url Prettyfier过滤器。过滤器将所有从/ 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 {

    }

}
Run Code Online (Sandbox Code Playgroud)