如何使用 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!
jakarta.servlet.http.HttpFilter
。doFilter()
方法中,使用 HttpServletRequest#getRequestURI()
来抓取路径。java.lang.String
方法,如substring()
、split()
、concat()
等来提取感兴趣的部分并组成新路径。ServletRequest#getRequestDispatcher()
然后使用 RequestDispatcher#forward()
将请求/响应转发到新 URL(服务器端重定向,不会反映在浏览器地址栏中),或 使用 HttpServletResponse#sendRedirect()
进行重定向对新 URL 的响应(客户端重定向,反映在浏览器地址栏中)。@WebFilter
或
url-pattern
的 /*
上的 /Check_License/*
注释注册过滤器,具体取决于上下文路径。不要忘记在代码中添加检查,如果 URL 需要更改,如果不需要,则只需调用
FilterChain#doFilter()
,否则它将在无限循环中调用自身。
或者,您也可以使用现有的第 3 方 API 来为您完成所有工作,例如 Tuckey 的 UrlRewriteFilter,它可以像使用 Apache 的
mod_rewrite
那样进行配置。
您可以使用现成的 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>
查看示例以获取更多...示例。
一个简单的 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 {
}
}
就我而言,我使用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() {}
}
确保链接修改后的请求
我已经检查了您的程序并进行了必要的更正。希望您的问题能够得到解决。
使用Servlet版本3.0
package mypackage;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet Filter implementation class RequestRedirectingFilter
*/
@WebFilter("/Dir_My_App/*")
public class RequestRedirectingFilter implements Filter {
private ServletContext context;
public void init(FilterConfig fConfig) throws ServletException {
this.context = fConfig.getServletContext();
System.out.println("RequestRedirectingFilter initialized.....................");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException,ServletException {
System.out.println("I am here........");
HttpServletResponse res=(HttpServletResponse)response;
res.sendRedirect("http://nm-java.appspot.com/Check_License?Contact_Id=My_Obj_123");
}
public void destroy() {
//we can close resources here
}
}
您可以在tomcat 9中部署此程序