Simple instance of Embedded Tomcat with a Servlet and a Filter:
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 Filter Implementation:
@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);
}
}
For some reason this ends up in an infinite loop and never arrives at Servlet1. What is the correct way of implementing a URL Filter so that I can double check the parameters around the request before delivering the response?
As this solved your problem, posting it as an answer.
Firstly, you need to ensure that you're either passing the request along the application filter chain, or you're redirecting it:
@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);
}
Then you need to ensure that the filter knows when an incoming request has already been redirected, so that it doesn't redirect it again:
@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);
}