I have a Servlet I want to bind to "/"
pattern. After that, all works fine for all URLs including application root but I also need the default
servlet for static files support.
After I add it into web.xml this way I got 404
error at the application root URL, but all other URLs are still successfully handled by the Servlet assigned to "/"
.
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
<url-pattern>*.css</url-pattern>
<url-pattern>*.js</url-pattern>
<servlet-mapping>
After I bind the Servlet also to ""
pattern it works fine. How I understand this pattern is related to the root URL of the application.
Could you help me to find out the reasons for such behavior?
P.S. I check the behavior with TomCat and Undertow.
I reproduced your issue using Apache Tomcat 9.0.21 and following servlet:
package my.sample;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Servlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("servlet1: " + req.getServletPath());
}
}
And web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
id="myApp" version="4.0">
<display-name>myWebApp</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>servlet1</servlet-name>
<servlet-class>my.sample.Servlet1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servlet1</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
<url-pattern>*.css</url-pattern>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
</web-app>
Opening the URL http://localhost:8080/myWebApp/
results in error 404 as described by you. Other URLs not matching any default
servlet url-pattern
are handled by my servlet1
and produce output like servlet1: /hello
for example when opening http://localhost:8080/myWebApp/hello
When removing the <url-pattern>*.html</url-pattern>
from default
servlet mapping, your issue is gone and I get servlet1: /
as response when opening http://localhost:8080/myWebApp/
.
When adding the <url-pattern>*.html</url-pattern>
to servlet1
servlet mapping I get servlet1: /index.html
as response when opening http://localhost:8080/myWebApp/
.
This suggests the reason for your issue is that path /
is internally forwarded to the welcome-file index.html which perfectly matches the *.html url-pattern configured for the default
servlet in your case - and thus the default
servlet is chosen to handle the /
request path. If an index.html is abscent, the default
servlet sends the 404 error observed by you.