如何在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!

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

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

或者,您也可以使用现有的第三方API来完成所有的工作,比如Tuckey的UrlRewriteFilter ,它可以像Apache的mod_rewrite一样进行配置。

你可以使用准备使用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> 

检查更多示例的示例。

请注意,如果您的原始网址包含参数,例如http://nm-java.appspot.com/Check_License/Dir_My_App/Dir_ABC/My_Obj_123param1 = A&param2 = B,那么这些参数也将被转发到下一个servlet / jsp。 我没有找到一种方法摆脱或替换原始参数(只能通过使用HttpServletRequestWrapper)。 有任何想法吗?..

更新:似乎http://ocpsoft.org/opensource/how-to-safely-add-modify-servlet-request-parameter-values/解决这个问题。;

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