如何在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!
- 实现
javax.servlet.Filter
。 - 在
doFilter()
方法中,将传入的ServletRequest
为HttpServletRequest
。 - 使用
HttpServletRequest#getRequestURI()
来获取路径。 - 使用像
substring()
,split()
,concat()
等直接的java.lang.String
方法来提取感兴趣的部分并组成新的路径。 - 使用
ServletRequest#getRequestDispatcher()
和RequestDispatcher#forward()
将请求/响应转发到新的URL(服务器端重定向,不会反映在浏览器地址栏中), 或者将传入的ServletResponse
为HttpServletResponse
,然后HttpServletResponse#sendRedirect()
将响应重定向到新的URL(客户端重定向,反映在浏览器地址栏中)。 - 将过滤器注册到
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_123 ? param1 = 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 { } }