Java 实现一个URL过滤器
带有Servlet和过滤器的嵌入式Tomcat的简单实例:Java 实现一个URL过滤器,java,tomcat,servlets,embedded-tomcat-7,tomcat8,Java,Tomcat,Servlets,Embedded Tomcat 7,Tomcat8,带有Servlet和过滤器的嵌入式Tomcat的简单实例: Tomcat tomcat = new Tomcat(); Context rootCtx = tomcat.addContext("", base.getAbsolutePath()); FilterDef filterDefinition = new FilterDef(); filterDefinition.setFilterName(
Tomcat tomcat = new Tomcat();
Context rootCtx = tomcat.addContext("", base.getAbsolutePath());
FilterDef filterDefinition = new FilterDef();
filterDefinition.setFilterName(URLFilter.class.getSimpleName());
filterDefinition.setFilterClass(URLFilter.class.getName());
rootCtx.addFilterDef(filterDefinition);
FilterMap filter1mapping = new FilterMap();
filter1mapping.setFilterName(URLFilter.class.getSimpleName());
filter1mapping.addURLPattern("/*");
rootCtx.addFilterMap(filter1mapping);
Tomcat.addServlet(rootCtx, "Servlet1", new Servlet1());
rootCtx.addServletMapping("/Servlet1", "Servlet1");
URL过滤器实现:
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
Boolean filtered = false;
System.out.println("request intercepted");
if (request.getAttribute("filtered") != null) {
filtered = true;
request.setAttribute("filtered", filtered);
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.sendRedirect("/Servlet1");
return;
} else {
filterChain.doFilter(request, response);
}
}
出于某种原因,这会在无限循环中结束,并且永远不会到达Servlet1。实现URL过滤器的正确方法是什么,这样我就可以在发送响应之前仔细检查请求周围的参数了?查看JavaDocs以了解更多信息。您在每个请求上都告诉客户机返回到/Servlet1,但随后您将无限期地对其进行过滤。在某个时候,您需要停止在过滤器中发送重定向
进一步澄清。如果您不打算主动筛选请求,那么您只需要调用
filterChain.dofilter(request, response);
不要发回重定向,除非你真的想发送HTTP 302(临时重定向)。Servlet筛选器链是Servlet流程的重要组成部分,尽管看起来有点违反直觉,但您可以通过调用filterChain.doFilter命令使筛选器看起来什么都不做,该命令允许请求继续处理由应用程序服务器配置的其他筛选器
我不清楚的是过滤你的过滤器试图做什么。如果您打算按URL进行筛选,则应查找匹配的URL,然后仅在存在匹配的URL时重定向。因为这解决了您的问题,所以将其作为答案发布 首先,您需要确保沿着应用程序筛选器链传递请求,或者重定向请求:
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
Boolean filtered = false;
System.out.println("request intercepted");
if (!filtered) {
filtered = true;
((HttpServletResponse) response).sendRedirect("/Servlet1");
return;
}
filterChain.doFilter(request, response);
}
然后,您需要确保过滤器知道传入请求何时已被重定向,以便不再重定向:
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
Boolean filtered = false;
System.out.println("request intercepted");
if (request.getAttribute("filtered") != null) {
filtered = (Boolean) request.getAttribute("filtered");
}
if (!filtered) {
request.setAttribute("filtered", Boolean.TRUE);
((HttpServletResponse) response).sendRedirect("/Servlet1");
return;
}
filterChain.doFilter(request, response);
}
看起来您缺少对
chain.doFilter(请求、响应)
的调用。如果您在doFilter
方法的末尾包含它,行为是否会改变?抱歉,我最初的评论太仓促,不够具体。只有在不发送重定向时,才需要调用doFilter
。当你重定向时,你应该返回
之后,doFilter
用于不重定向时。如果要执行大量重定向,请查看。它就是为了这个目的而做的。也许可以试着从这个角度来看它:你的过滤器如何知道它之前是否已经重定向了一个请求?目前它没有-它假设它接收到的任何东西还没有被重定向,并重定向它。您可以向请求添加一个属性,例如request.setAttribute(“redirected”,“true”)
,然后让筛选器检查该属性以查看它是否已重定向。如果没有,请修改属性然后重定向它,否则不要重定向它并沿着应用程序筛选器链传递请求。这是,但我认为如果(request.getRequestURI.equals(“/Servlet1”){filterChain.dofilter(request,response);}