【问题标题】:How to use a servlet filter in Java to change an incoming servlet request url?如何在 Java 中使用 servlet 过滤器来更改传入的 servlet 请求 url?
【发布时间】:2018-07-31 02:35:40
【问题描述】:

如何使用 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() {
        //
    }
}

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!

【问题讨论】:

标签: java url servlets request servlet-filters


【解决方案1】:
  1. 实现javax.servlet.Filter
  2. doFilter() 方法中,将传入的ServletRequest 转换为HttpServletRequest
  3. 使用HttpServletRequest#getRequestURI() 抓取路径。
  4. 使用简单的java.lang.String 方法,如substring()split()concat() 等来提取感兴趣的部分并组成新路径。
  5. 使用ServletRequest#getRequestDispatcher()RequestDispatcher#forward() 将请求/响应转发到新的URL(服务器端重定向,不反映在浏览器地址栏中),转换传入的@987654332 @ 到HttpServletResponse 然后HttpServletResponse#sendRedirect() 将响应重定向到新的URL(客户端重定向,反映在浏览器地址栏中)。
  6. url-pattern/*/Check_License/* 上注册web.xml 中的过滤器,具体取决于上下文路径,或者如果您已经使用Servlet 3.0,请改用@WebFilter 注释。

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

或者,您也可以只使用现有的 3rd 方 API 为您完成所有工作,例如 Tuckey's UrlRewriteFilter,可以像使用 Apache 的 mod_rewrite 一样进行配置。

【讨论】:

  • 是否有任何 doFilter() 示例代码可以执行上述操作?谢谢。
  • 你到底卡在哪一步了?我的回答几乎是自己编写代码。您是否还注意到蓝色的代码引用实际上是指向详细描述类/方法行为的 Javadocs 的链接?不管怎样,你都可以找到 herehere 很好的 JSP/Servlet 教程,特别是 this 一个关于过滤器的教程。
  • 我认为它是正确的,但是如果过滤器是链中的第一个过滤器,并且执行了RequestDispatcher#forward(),则不会执行其余过滤器。那么,作为 servlet 执行此操作不是更好的方法吗?
  • @datakey:只需重新排列顺序或添加 &lt;dispatcher&gt;FORWARD&lt;/dispatcher&gt; 到过滤器映射。
  • @BalusC 我们可以在不重定向或呼叫转发的情况下做到这一点吗?
【解决方案2】:

您可以将准备使用的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>

查看Examples 了解更多...示例。

【讨论】:

  • 您好,粘贴的链接已失效。它的 404 在那里。请您更改为其他来源。谢谢。
【解决方案3】:

一个基于BalusC's answer 步骤的简单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 {

    }

}

【讨论】:

    猜你喜欢
    • 2016-03-13
    • 2017-08-20
    • 2015-09-12
    • 2010-11-27
    • 2015-10-28
    • 2014-09-13
    • 2015-09-15
    相关资源
    最近更新 更多