Может ли кто-нибудь объяснить отображение сервлетов?

StackOverflow https://stackoverflow.com/questions/234210

Вопрос

Я пытаюсь написать веб-приложение, используя SpringMVC.Обычно я просто сопоставляю какое-то выдуманное расширение файла с передним контроллером Spring и живу счастливо, но на этот раз я выбираю URL-адреса, подобные REST, без расширений имен файлов.

Сопоставление всего моего контекстного пути с фронт-контроллером (назовем это "приложение") означает, что я также должен позаботиться о статических файлах, чего я бы предпочел не делать (зачем изобретать еще одну штуку?), поэтому некоторая комбинация с сервлетом 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>

Может ли кто-нибудь пролить свет?

Это было полезно?

Решение

Думаю, я знаю, что происходит.

В вашем рабочем 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) отбрасывает отображение сервлета и пытается найти файл, используя оставшийся путь. Согласно этому сообщению Сервлет для обслуживания статического контента Jetty показывает поведение, которое вы и я ожидали.

По какой-то причине вы не можете сделать что-то вроде сопоставления корневого каталога для ваших остальных вызовов? Что-то вроде приложения, сопоставленного с / rest_root / *, чем вы несете ответственность за все, что происходит в папке rest_root, но в любом другом месте должен обрабатываться Tomcat, если вы не сделаете другое явное сопоставление. Я предлагаю настроить ваш оставшийся сервлет на отображение пути, потому что оно объявляет намерение лучше. Использование / или / * не представляется целесообразным, так как вы должны отобразить исключения. Используя SO в качестве примера, мои остальные сопоставления будут выглядеть примерно так:

  

/ users / * для пользовательского сервлета

     

/ posts / * для сервлета сообщений

Порядок отображения

<Ол>
  • Явный (отображение пути)
  • Неявный (сопоставления расширений)
  • По умолчанию (/)
  • Пожалуйста, исправьте все, что я ошибся.

    Другие советы

    Для справки: «неудачная попытка №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>
    

    Я никогда не пытался отобразить сервлет, подобный этому, но я хотел бы утверждать, что / * технически оба начинаются с / и заканчиваются на / *, хотя один и тот же символ используется для обоих совпадения.

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top