Разница между / и / * в шаблоне url сопоставления сервлетов



знакомый код:



<servlet-mapping>
<servlet-name>main</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

<servlet-mapping>
<servlet-name>main</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>


мое понимание заключается в том, что /* карты http://host:port/context/*.



как о /? Это точно не соответствует

698   5  

5 ответов:

<url-pattern>/*</url-pattern>

The /* на сервлете переопределяет все другие сервлеты, включая все сервлеты, предоставляемые сервлетконтейнером, такие как сервлет по умолчанию и сервлет JSP. Какой бы запрос вы ни запустили, он окажется в этом сервлете. Таким образом, это плохой шаблон URL для сервлетов. Обычно, вы хотели бы использовать /* на Filter только. Он может позволить запросу продолжить любой из сервлетов, прослушивающих более конкретный шаблон URL, вызвав FilterChain#doFilter().

<url-pattern>/</url-pattern>

The / не переопределяет любой другой сервлет. Он заменяет только встроенный сервлет servletcontainer по умолчанию для всех запросов, который не соответствует никакому другому зарегистрированному сервлету. Обычно это вызывается только для статических ресурсов (CSS/JS/image / etc) и списков каталогов. Встроенный сервлет servletcontainer по умолчанию также способен обрабатывать запросы кэша HTTP, потоковую передачу мультимедиа (аудио/видео) и загрузку файлов возобновляет. Обычно вы не хотите переопределять сервлет по умолчанию, так как в противном случае вам придется заботиться обо всех его задачах, что не совсем тривиально (JSF utility library OmniFaces есть open sourceпример). Таким образом, это также плохой шаблон URL для сервлетов. Что касается того, почему страницы JSP не попадают в этот сервлет, это потому, что встроенный сервлет JSP servletcontainer будет вызван, который уже по умолчанию сопоставлен с более конкретным URL шаблон *.jsp.

<url-pattern></url-pattern>

тогда есть также пустая строка URL pattern . This will be invoked when the context root is requested. This is different from the <welcome-file> подход, что он не вызывается, когда любой папке запрашивается. Это, скорее всего, шаблон URL, который вы на самом деле ищете, если вы хотите "Домашняя страница сервлет". Я только должен признать, что я интуитивно ожидаю пустую строку URL pattern и Слэш URL pattern / быть определены точно наоборот, так что я могу поймите, что многие начинающие запутались в этом. Но это то, что есть.

Фронт-Контроллера

в случае, если вы на самом деле намеревайтесь иметь сервлет переднего контроллера, тогда вам лучше всего сопоставить его с более конкретным шаблоном URL, таким как *.html,*.do,/pages/*,/app/* и т. д. Вы можете скрыть шаблон URL переднего контроллера и покрыть статические ресурсы на общем шаблоне URL, таком как /resources/*,/static/* и т. д. С помощью servlet фильтр. Смотреть также как предотвратить обработку статических ресурсов сервлетом переднего контроллера, который отображается на /*. Следует отметить, что Spring MVC имеет встроенный статический сервлет ресурсов, поэтому вы можете отобразить его передний контроллер на / если вы настроите общий шаблон URL для статических ресурсов весной. Смотрите также как обрабатывать статическое содержимое в Spring MVC?

Я хотел бы дополнить ответ BalusC правилами отображения и примером.

правила отображения из сервлета 2.5 спецификация:

  1. точный URL карты
  2. карта путей по шаблону
  3. карта расширения
  4. сопоставление с сервлетом по умолчанию

в нашем примере, есть три сервлеты. / является сервлетом по умолчанию, установленным нами. Tomcat устанавливает два сервлета для обслуживания jsp и jspx. Так что на карту http://host:port/context/hello

  1. не установлены точные сервлеты URL, далее.
  2. не установлены сервлеты подстановочных путей, далее.
  3. не соответствует никаким расширениям, далее.
  4. сопоставление с сервлетом по умолчанию, возврат.

на карте http://host:port/context/hello.jsp

  1. не установлены точные сервлеты URL, далее.
  2. не установлены сервлеты подстановочных путей, далее.
  3. найдено расширение сервлета, возврат.

Возможно, вам нужно знать, как URL-адреса отображаются тоже, так как я страдал 404 в течение нескольких часов. Существует два вида обработчиков, обрабатывающих запросы. BeanNameUrlHandlerMapping и SimpleUrlHandlerMapping. Когда мы определили servlet-mapping, мы используем SimpleUrlHandlerMapping. Одна вещь, которую нам нужно знать, это то, что эти два обработчика имеют общее свойство под названием alwaysUseFullPath значение по умолчанию false.

false здесь означает, что Spring не будет использовать полный путь к mapp url-адрес контроллера. Что это значит? Это означает, что при определении servlet-mapping:

<servlet-mapping>
    <servlet-name>viewServlet</servlet-name>
    <url-pattern>/perfix/*</url-pattern>
</servlet-mapping>

обработчик будет использовать * часть, чтобы найти контроллер. Например, следующий контроллер столкнется с 404 ошибка при запросе с помощью /perfix/api/feature/doSomething

@Controller()
@RequestMapping("/perfix/api/feature")
public class MyController {
    @RequestMapping(value = "/doSomething", method = RequestMethod.GET) 
    @ResponseBody
    public String doSomething(HttpServletRequest request) {
        ....
    }
}

это идеальный матч, не так ли? Но почему 404. Как упоминалось ранее, значение по умолчанию alwaysUseFullPath является ложным, что означает в вашем запросе, только /api/feature/doSomething используется для поиска соответствующего контроллера, но контроллер не заботится об этом пути. Вам нужно либо измените свой url на /perfix/perfix/api/feature/doSomething или удалить perfix из базы MyController @RequestingMapping.

Я думаю, что ответ Кэнди в основном правильный. Есть одна маленькая часть, которую я считаю иначе.

для отображения хоста: порт / контекст / привет.jsp

  1. не установлены точные сервлеты URL, далее.
  2. найдены подстановочные пути сервлетов, вернуть.

Я считаю, что почему " / * "не соответствует host:port/context/hello, потому что он рассматривает" /hello " как путь вместо файла (поскольку он не имеет расширения).

существенная разница между /* и / заключается в том, что сервлет с отображением /* будет выбран перед любым сервлетом с отображением расширения (например *.html), в то время как сервлет сопоставления с / будет выбран только после рассмотрения сопоставлений расширений (и будет использоваться для любого запроса, который не соответствует ничему другому---это "сервлет по умолчанию").

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

либо будет выбран только после сопоставления сервлетов, которые являются точными совпадениями (например /foo/bar), и те, которые являются отображениями путь длиннее, чем /* (типа /foo/*). Обратите внимание, что отображение пустой строки точно соответствует корневому контексту (http://host:port/context/).

см. Главу 12 спецификации сервлета Java, доступной в версии 3.1 at http://download.oracle.com/otndocs/jcp/servlet-3_1-fr-eval-spec/index.html.

Comments

    Ничего не найдено.