Может ли кто-нибудь объяснить отображение сервлетов?
Я пытаюсь написать веб-приложение с помощью SpringMVC. Обычно я просто сопоставляю некоторые расшифрованные расширения файлов с внешним контроллером Spring и живу счастливо, но на этот раз я собираюсь использовать URL-адреса типа REST без расширений имени файла.
Сопоставление всего, что связано с моим контекстным путём к переднему контроллеру (пусть его называют " приложение" ) означает, что я должен позаботиться и о статических файлах, чего я бы предпочел не делать (зачем изобретать еще один weel?), поэтому некоторая комбинация с сервлетом по умолчанию tomcat (пусть назовет его " tomcat" ), похоже, будет способом.
У меня получилось что-то вроде
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>tomcat</servlet-name>
<url-pattern>*.ext</url-pattern>
</servlet-mapping>
и повторить последнее для каждого из файлов расширения моего статического содержимого. Мне просто интересно, почему следующие настройки, которые для меня эквивалентны выше, не работают.
<!-- failed attempt #1 -->
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>tomcat</servlet-name>
<url-pattern>*.ext</url-pattern>
</servlet-mapping>
<!-- failed attempt #2 -->
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>tomcat</servlet-name>
<url-pattern>/some-static-content-folder/*</url-pattern>
</servlet-mapping>
Может ли кто-нибудь пролить свет?
Ответы
Ответ 1
Думаю, я знаю, что происходит.
В вашем рабочем web.xml вы установили, что ваш сервлет является сервлетом по умолчанию (/сам по себе является сервлетом по умолчанию, если нет других совпадений), он будет отвечать на любой запрос, который не соответствует другому сопоставлению.
В Failed 1 ваше /* -отображение действительно является допустимым сопоставлением пути. С отображением /* в web.xml он отвечает на все запросы, кроме других сопоставлений пути. В соответствии с отображением расширения спецификации подразумеваются неявные сопоставления, которые перезаписываются явными сопоставлениями. Вот почему неудачное сопоставление расширений. Все было явно сопоставлено с приложением.
В Failed 2 приложение отвечает за все, кроме содержимого, которое соответствует отображению статического содержимого. Чтобы показать, что происходит в быстром тесте, я настроил. Вот пример. /some-static-content-folder/
содержит test.png
Попытка доступа к test.png Я пробовал:
/some-static-content-folder/test.png
и файл не найден. Однако при попытке
/some-static-content-folder/some-static-content-folder/test.png
он появляется. Похоже, что сервлет Tomcat по умолчанию (по крайней мере, 6.0.16) снижает отображение сервлета и будет пытаться найти файл, используя оставшийся путь. В соответствии с этим сообщением Servlet для обслуживания статического содержимого Jetty дает поведение, которое вы и я ожидали.
Есть ли причина, по которой вы не можете сделать что-то вроде карты корневого каталога для ваших остальных вызовов. Что-то вроде приложения, сопоставленного с /rest _root/*, чем вы несете ответственность за все, что происходит в папке rest_root, но где-нибудь еще нужно обрабатывать Tomcat, если вы не сделаете другое явное сопоставление. Я предлагаю настроить сервлет вашего отдыха на сопоставление маршрутов, потому что он заявляет о намерении лучше. Использование/или/* кажется вам нецелесообразным, так как вы должны отображать исключения. Используя SO в качестве примера, мои сопоставления с отдыхом будут чем-то вроде
/users/* для сервлета пользователя
/posts/* для сервлета сообщений
Порядок отображения
- Явные (сопоставления пути)
- Неявные (расширения).
- По умолчанию (/)
Пожалуйста, исправьте все, что у меня получилось.
Ответ 2
Для справки, "неудачная попытка № 2" совершенно корректна в версии Tomcat >= 6.0.29.
Это был результат ошибки Tomcat, которая исправлена в версии 6.0.29:
https://issues.apache.org/bugzilla/show_bug.cgi?id=50026
<!-- Correct for Tomcat >= 6.0.29 or other Servlet containers -->
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/some-static-content-folder/*</url-pattern>
</servlet-mapping>
Ответ 3
Я никогда не пытался сопоставить такой сервлет, но я бы сказал, что /* технически и начинается с/и заканчивается на /*, хотя тот же символ используется для обоих совпадений.