I was working on a project where based on the presence of a particular string in the request URL to a web application, I was trying to modify the URL of the request using a request wrapper.
I learnt that even if I override the getRequestURI, getRequestURL and getServletPath methods in the wrapper and send that wrapper from a filter, the servlet container still uses its own implementation of the ServletRequest interface to figure out which servlet to call.
I believe the container uses the stored variable for the request URI in the implementation class of ServletRequest and doesn't actually call any of the getRequestURI, getRequestURL and getServletPath methods for identifying the servlet to use (matching URL pattern).
Need all your inputs and knowledge to learn more about this topic. Please help me learn this topic better. Thanks..!!
Below are my experimental code and the request comes from the jsp for http://localhost:8080/RequestResponseListenersWebApp/pages/abcd.jsp
The Filter
@WebFilter(filterName = "AllRequestScanFilter", urlPatterns = "/*")
public class AllRequestScanFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
EmployerViewTestBusinessWrapper wrapper = new EmployerViewTestBusinessWrapper(request);
if (request.getRequestURI().contains("abcd.jsp"))
chain.doFilter(wrapper, resp);
else {
chain.doFilter(req, resp);
}
}
public void init(FilterConfig config) throws ServletException {
}
}
The Wrapper
public class EmployerViewTestBusinessWrapper extends HttpServletRequestWrapper {
public EmployerViewTestBusinessWrapper(HttpServletRequest request) {
super(request);
}
@Override
public String getPathTranslated() {
return super.getPathTranslated();
}
@Override
public String getRequestURI() {
String currentPath=pathModified(super.getRequestURI());
return currentPath!=null?currentPath:super.getRequestURI();
}
@Override
public StringBuffer getRequestURL() {
String currentPath=pathModified(super.getRequestURL().toString());
return currentPath!=null?new StringBuffer(currentPath):new StringBuffer(super.getRequestURL());
}
@Override
public String getServletPath() {
String currentPath=pathModified(super.getServletPath());
return currentPath!=null?currentPath:super.getServletPath();
}
private String pathModified(String currentPath){
String returnPath=null;
if(currentPath.contains("pages")){
returnPath=currentPath.replaceFirst("/pages/","/pages/myapp/");
}
return returnPath;
}
}
The Servlet which is never reached
@WebServlet(name = "EmployerViewTestServlet",urlPatterns = "/pages/myapp/*")
public class EmployerViewTestServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String path=request.getParameter("path");
}
}
And one more thing. The Filter I have specified here is the first thing in the web app that's called when a request comes in.
I can always check the URL pattern in the filter and forward the request to the desired URL pattern using a RequestDispatcher.
However, in my app there're some Filters that are called for dispatcher type FORWARD and I don't want them to be called when a request has just come from the client.