关于 Servlet 绑定模式和默认 servlet
About Servlet binding patterns and default servlet
我有一个要绑定到 "/"
模式的 Servlet。之后,所有 URL 都可以正常工作,包括应用程序根目录,但我还需要 default
servlet 来支持静态文件。
在我以这种方式将其添加到 web.xml 之后,我在应用程序根目录 URL 处遇到了 404
错误,但所有其他 URL 仍由分配给 "/"
.
的 Servlet
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
<url-pattern>*.css</url-pattern>
<url-pattern>*.js</url-pattern>
<servlet-mapping>
在我将 Servlet 也绑定到 ""
模式后,它工作正常。我对这种模式的理解与应用程序的根 URL 有关。
你能帮我找出这种行为的原因吗?
P.S。我用 TomCat 和 Undertow 检查行为。
我使用 Apache Tomcat 9.0.21 和以下 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());
}
}
和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>
如您所述,打开 URL http://localhost:8080/myWebApp/
会导致错误 404。其他 URL 不匹配任何 default
servlet url-pattern
由我的 servlet1
处理并产生类似 servlet1: /hello
的输出,例如打开 http://localhost:8080/myWebApp/hello
从 default
servlet 映射中删除 <url-pattern>*.html</url-pattern>
时,您的问题消失了,我在打开 http://localhost:8080/myWebApp/
.
时收到 servlet1: /
作为响应
将 <url-pattern>*.html</url-pattern>
添加到 servlet1
servlet 映射时,我在打开 http://localhost:8080/myWebApp/
.
时得到 servlet1: /index.html
作为响应
这表明您的问题的原因是路径 /
在内部转发到欢迎文件 index.html,它与 *.html url- 完全匹配在您的案例中为 default
servlet 配置的模式 - 因此选择 default
servlet 来处理 /
请求路径。如果 index.html 不存在,default
servlet 将发送您观察到的 404 错误。
我有一个要绑定到 "/"
模式的 Servlet。之后,所有 URL 都可以正常工作,包括应用程序根目录,但我还需要 default
servlet 来支持静态文件。
在我以这种方式将其添加到 web.xml 之后,我在应用程序根目录 URL 处遇到了 404
错误,但所有其他 URL 仍由分配给 "/"
.
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
<url-pattern>*.css</url-pattern>
<url-pattern>*.js</url-pattern>
<servlet-mapping>
在我将 Servlet 也绑定到 ""
模式后,它工作正常。我对这种模式的理解与应用程序的根 URL 有关。
你能帮我找出这种行为的原因吗?
P.S。我用 TomCat 和 Undertow 检查行为。
我使用 Apache Tomcat 9.0.21 和以下 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());
}
}
和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>
如您所述,打开 URL http://localhost:8080/myWebApp/
会导致错误 404。其他 URL 不匹配任何 default
servlet url-pattern
由我的 servlet1
处理并产生类似 servlet1: /hello
的输出,例如打开 http://localhost:8080/myWebApp/hello
从 default
servlet 映射中删除 <url-pattern>*.html</url-pattern>
时,您的问题消失了,我在打开 http://localhost:8080/myWebApp/
.
servlet1: /
作为响应
将 <url-pattern>*.html</url-pattern>
添加到 servlet1
servlet 映射时,我在打开 http://localhost:8080/myWebApp/
.
servlet1: /index.html
作为响应
这表明您的问题的原因是路径 /
在内部转发到欢迎文件 index.html,它与 *.html url- 完全匹配在您的案例中为 default
servlet 配置的模式 - 因此选择 default
servlet 来处理 /
请求路径。如果 index.html 不存在,default
servlet 将发送您观察到的 404 错误。