[context] tomcat 7 - java 1.7
Hey everyone; I'm facing with stranges working. In my web.xml file, I mapped request like this :
web.xml
<web-app>
<filter>
<filter-name>filter</filter-name>
<filter-class>demo.DemoFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>Servlet</servlet-name>
<servlet-class>demo.DemoServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
DemoFilter.java (implements Filter)
@Override
public void doFilter( ServletRequest req, ServletResponse res, FilterChain chain )
throws IOException, ServletException
{
try
{
chain.doFilter(req, res);
}
catch ( Exception e )
{
System.err.println("error");
((HttpServletResponse) res).setContentType("text/html");
((HttpServletResponse) res).setStatus(HttpServletResponse.SC_NOT_FOUND);
res.getWriter().write("foo");
}
}
DemoServlet.java (extends HttpServlet)
@Override
protected void doGet( HttpServletRequest req, HttpServletResponse resp )
throws ServletException, IOException
{
System.err.println(req.getRequestURI());
throw new RuntimeException("ERROR");
}
[1 = Expected result] First, when I tried to request "/foo/bar", the filter and the servlet were called (and the page display the word 'foo'). Console result :
/foo/bar
error
[2 = Unexpected result] Then, when I tried to request "/WEB-INF/foo/bar", nothing was called (my filter and my servlet were not hit) and I get a Tomcat error report :
HTTP Status 404 -
type Status report
message
description The requested resource is not available.
Apache Tomcat/7.0.30
EDIT : Here, I expected to get the following result :
/WEB-INF/foo/bar
error
I aim to use my Filter to handle Exception ("/WEB-INF" calls included).
- Why request which start with "/WEB-INF/" never hit filter/servlet mapped on "/*" pattern ?
- How can we solve this problem?
Thanks in advance!
PS : I would like to keep my current web.xml configuration ("url-pattern" = "/*" ; without using "error-page")
EDIT : My question was misunderstood. I don't want to serve file access under my "WEB-INF" directory. I want to serve every request with my Filter and Servlet (url-pattern='/*') even if the request URI start with "/WEB-INF/". Thanks !
There's a major conceptual misunderstanding here. Resources in
/WEB-INF
aren't publicly accessible at all. The way how you put the question indicates otherwise. This is not right. I believe that you just asked about the concrete problem the wrong way.Based on a comment, I understood that you wanted to log accessed files in
/WEB-INF
as well as 404 errors. I guess that you actually meant that you want to log forwarded, included and error'ed resources as well next to directly requested resources. Normally, the forwarded and included resources are indeed hidden in/WEB-INF
to prevent direct access.A filter is by default invoked on directly requested resources only, not on forwarded and included resources nor on error'ed resources like in your 404 attempt. For that you need to add the appropriate
<dispatcher>
entries to the mapping:(each of them are optional; the
REQUEST
is the default one when totally absent)This way the filter will not only intercept on directly requested resources, but also on forwarded, included and error'ed resources. The
ERROR
dispatcher will make it to kick in on the 404 error as well.According to the servlet specification, any requests from the client to access the resources in WEB-INF/ directory must be returned with a SC_NOT_FOUND(404) response. See section 10.5 Directory Structure.
https://download.oracle.com/otn-pub/jcp/servlet-3_1-fr-eval-spec/servlet-3_1-final.pdf https://download.oracle.com/otn-pub/jcp/servlet-3.0-fr-eval-oth-JSpec/servlet-3_0-final-spec.pdf
If you want to restrict direct URL access to some files, put them under WEB-INF directory.
Quote from here: http://www.servletworld.com/servlet-tutorials/web-application-directory-structure.html
Both answers posted are correct and this is the same for any application server you use and JDK. Although from servlet specification 3.0 web.xml is optional or you could use web-framgment.xml to break web.xml.
WEB-INF directory is a private area of the web application, any files under WEB-INF directory cannot be accessed directly from browser by specifying the URL like the way you've specified.
The web container will not serve the content of this directory. However the content of the this directory is accessible by the classes, like the servlets that you've mapped in your web.xml within the application.