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

如何使用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!

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

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

或者,你也可以使用一个现有的第三方API来为你做所有的工作,比如塔基的UrlRewriteFilter,它可以像你使用Apache的mod_rewrite一样配置。

你可以使用ready来使用Url重写过滤器,规则如下:

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

检查例子更多…的例子。

一个简单的基于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 {


}


}

在我的情况下,我使用Spring和由于某种原因forrward没有与我一起工作,所以我做了以下工作:

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() {}
}

确保链接了modifiedRequest