简体   繁体   English

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

[英]How to use a servlet filter in Java to change an incoming servlet request url?

How can I use a servlet filter to change an incoming servlet request url from如何使用 servlet 过滤器更改传入的 servlet 请求 url 来自

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

to

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

?


Update : according to BalusC's steps below, I came up with the following code:更新:根据下面 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() {
        //
    }
}

The relevant entry in web.xml look like this: 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>

I tried both server-side and client-side redirect with the expected results.我尝试了服务器端和客户端重定向,得到了预期的结果。 It worked, thanks BalusC!成功了,感谢 BalusC!

  1. Implement javax.servlet.Filter .实现javax.servlet.Filter
  2. In doFilter() method, cast the incoming ServletRequest to HttpServletRequest .doFilter()方法中,将传入的ServletRequestHttpServletRequest
  3. Use HttpServletRequest#getRequestURI() to grab the path.使用HttpServletRequest#getRequestURI()获取路径。
  4. Use straightforward java.lang.String methods like substring() , split() , concat() and so on to extract the part of interest and compose the new path.使用简单的java.lang.String方法,如substring()split()concat()等来提取感兴趣的部分并组成新路径。
  5. Use either ServletRequest#getRequestDispatcher() and then RequestDispatcher#forward() to forward the request/response to the new URL (server-side redirect, not reflected in browser address bar), or cast the incoming ServletResponse to HttpServletResponse and then HttpServletResponse#sendRedirect() to redirect the response to the new URL (client side redirect, reflected in browser address bar).使用ServletRequest#getRequestDispatcher()然后RequestDispatcher#forward()将请求/响应转发到新 URL(服务器端重定向,未反映在浏览器地址栏中),将传入的ServletResponseHttpServletResponse ,然后HttpServletResponse#sendRedirect()将响应重定向到新的 URL(客户端重定向,反映在浏览器地址栏中)。
  6. Register the filter in web.xml on an url-pattern of /* or /Check_License/* , depending on the context path, or if you're on Servlet 3.0 already, use the @WebFilter annotation for that instead.web.xml中以/*/Check_License/*url-pattern注册过滤器,具体取决于上下文路径,或者如果您已经在 Servlet 3.0 上,请改用@WebFilter批注。

Don't forget to add a check in the code if the URL needs to be changed and if not , then just call FilterChain#doFilter() , else it will call itself in an infinite loop.如果 URL需要更改,请不要忘记在代码中添加检查,如果不需要,则只需调用FilterChain#doFilter() ,否则它将在无限循环中调用自身。

Alternatively you can also just use an existing 3rd party API to do all the work for you, such as Tuckey's UrlRewriteFilter which can be configured the way as you would do with Apache's mod_rewrite .或者,您也可以使用现有的 3rd 方 API 来为您完成所有工作,例如Tuckey 的 UrlRewriteFilter ,它可以像使用 Apache 的mod_rewrite一样进行配置。

You could use the ready to use Url Rewrite Filter with a rule like this one:您可以将准备使用的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>

Check the Examples for more... examples.查看示例以获取更多...示例。

A simple JSF Url Prettyfier filter based in the steps of BalusC's answer .基于BalusC's answer步骤的简单 JSF Url Prettyfier 过滤器。 The filter forwards all the requests starting with the /ui path (supposing you've got all your xhtml files stored there) to the same path, but adding the xhtml suffix.过滤器将所有以 /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 {

    }

}

In my case, I use Spring and for some reason forward did not work with me, So I did the following:就我而言,我使用 Spring 并且由于某种原因forward对我不起作用,所以我做了以下操作:

public class OldApiVersionFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        if (httpServletRequest.getRequestURI().contains("/api/v3/")) {
            HttpServletRequest modifiedRequest = new HttpServletRequestWrapper((httpServletRequest)) {
                @Override
                public String getRequestURI() {
                    return httpServletRequest.getRequestURI().replaceAll("/api/v3/", "/api/");
                }
            };
            chain.doFilter(modifiedRequest, response);
        } else {
            chain.doFilter(request, response);
        }
    }

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

    @Override
    public void destroy() {}
}

Make sure you chain the modifiedRequest确保链接 modifiedRequest

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM