О шаблонах привязки сервлета и сервлете по умолчанию - PullRequest
0 голосов
/ 08 октября 2019

У меня есть сервлет, который я хочу привязать к шаблону "/". После этого все работает нормально для всех URL, включая корень приложения, но мне также нужен сервлет default для поддержки статических файлов.

После того, как я добавил его в web.xml, я получил ошибку 404 вкорневой URL-адрес приложения, но все остальные 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>

После того, как я также связал сервлет с шаблоном "", он работает нормально. Насколько я понимаю, этот шаблон связан с корневым URL-адресом приложения.

Не могли бы вы помочь мне выяснить причины такого поведения?

PS Я проверяю поведение с TomCat и Undertow.

1 Ответ

1 голос
/ 09 октября 2019

Я воспроизвел вашу проблему, используя Apache Tomcat 9.0.21 и следующий сервлет:

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 сервлету url-pattern, обрабатываются моим servlet1 и выдают результат, такой как servlet1: /hello, например, при открытии http://localhost:8080/myWebApp/hello

При удалении <url-pattern>*.html</url-pattern> из default сервлетасопоставлении, ваша проблема исчезла, и я получаю servlet1: / в качестве ответа при открытии http://localhost:8080/myWebApp/.

При добавлении сопоставления сервлета <url-pattern>*.html</url-pattern> в servlet1 я получаю servlet1: /index.html в качестве ответа при открытии http://localhost:8080/myWebApp/.

Это говорит о том, что причина вашей проблемы заключается в том, что путь / внутренне перенаправляется в файл приветствия index.html, который полностью соответствует шаблону URL * .html, настроенному для сервлета default в вашемcase - и, таким образом, сервлет default выбран для обработки пути запроса /. Если index.html отсутствует, сервлет default отправляет наблюдаемую вами ошибку 404.

...