public static int compareVersions (String version1, String version2) {String [] levels1 = version1.split ("\\."); String [] levels2 = version2.split ("\\."); int length = Math.max (levels1.length, levels2.length); for (int i = 0; i & lt; length; i ++) {Integer v1 = i & lt; levels1.length? Integer.parseInt (levels1 [i]): 0; Целое число v2 = i & lt; levels2.length? Integer.parseInt (levels2 [i]): 0; int compare = v1.compareTo (v2); if (compare! = 0) {return compare; }} return 0; }
<url-pattern>/*</url-pattern>
/*
на сервлете переопределяет все другие сервлеты, включая все сервлеты, предоставленные сервером сервлетов, такие как сервлет по умолчанию и сервлет JSP. Какой бы запрос вы ни стреляли, он попадет в этот сервлет. Таким образом, это плохой шаблон URL для сервлетов. Обычно вы хотите использовать /*
только на Filter
. Он может разрешить запросу любой сервлет, прослушивающий более конкретный шаблон URL, вызывая FilterChain#doFilter()
.
<url-pattern>/</url-pattern>
/
не отменяет никакого другого сервлета. Он заменяет только встроенный сервлет servletcontainer по умолчанию для всех запросов, которые не соответствуют никакому другому зарегистрированному сервлету. Обычно это делается только для статических ресурсов (CSS / JS / image / etc) и списков каталогов. Встроенный по умолчанию сервлет servletcontainer также способен обрабатывать запросы HTTP-кеша, потоковое воспроизведение мультимедиа (аудио / видео) и возобновление загрузки файлов. Как правило, вы не хотите переопределять сервлет по умолчанию, как в противном случае вам приходилось бы заботиться обо всех своих задачах, что не совсем тривиально (библиотека JSF-утилиты OmniFaces имеет с открытым исходным кодом пример ). Это, таким образом, также плохой шаблон URL для сервлетов. Что касается того, почему страницы JSP не попадают в этот сервлет, это происходит из-за того, что будет запущен встроенный JSP-сервлет servletcontainer, который по умолчанию отображается на более конкретном шаблоне URL *.jsp
.
<url-pattern></url-pattern>
Тогда есть также пустая строка URL-адреса . Это будет вызвано при запросе корня контекста. Это отличается от подхода
<welcome-file>
, что он не вызывается, когда запрашивается любая вложенная папка. Скорее всего, это шаблон URL, который вы на самом деле ищете, если вам нужен сервлет домашней страницы ". Я должен только признать, что интуитивно ожидаю, что пустая строка URL-шаблона и шаблон косой черты
/
будут определены точно так же, как и наоборот, поэтому я могу понять, что многие пускатели путались в этом.
Если вы на самом деле намереваетесь иметь сервлет суперконтроллера, тогда вам лучше всего его сопоставить более конкретный шаблон URL, например *.html
, *.do
, /pages/*
, /app/*
и т. д. Вы можете скрыть шаблон URL-адреса переднего контроллера и покрыть статические ресурсы на общем шаблоне URL, например /resources/*
, /static/*
, и т. д. с помощью фильтра сервлетов. См. Также . Как предотвратить использование статических ресурсов сервлетом переднего контроллера, который отображается на / * . Следует отметить, что Spring MVC имеет встроенный статический сервлет ресурсов, поэтому вы можете сопоставить его фронт-контроллер на /
, если вы настроили общий шаблон URL для статических ресурсов в Spring. См. Также Как обрабатывать статический контент в Spring MVC?
Возможно, вам нужно знать, как отображаются URL-адреса, так как я страдал 404
в течение нескольких часов. Существует два типа обработчиков, обрабатывающих запросы. BeanNameUrlHandlerMapping
и SimpleUrlHandlerMapping
. Когда мы определили servlet-mapping
, мы используем SimpleUrlHandlerMapping
. Мы должны знать, что эти два обработчика имеют общее свойство, называемое alwaysUseFullPath
, которое по умолчанию имеет значение false
.
false
здесь означает, что Spring не будет использовать полный путь для преобразования 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
равно false, что означает, что в вашем запросе используется только /api/feature/doSomething
, чтобы найти соответствующий контроллер, но Controller не заботится об этом пути. Вам нужно либо изменить свой URL на /perfix/perfix/api/feature/doSomething
, либо удалить perfix
с базы MyController @RequestingMapping
.
Я думаю, что ответ Кенди в основном верен.
Чтобы отобразить узел: port / context / hello.jsp
Я считаю, что почему «/ *» не соответствует хосту: port / context / hello, потому что он рассматривает «/ hello» как путь вместо файл (поскольку он не имеет расширения).
Существенное различие между /*
и /
заключается в том, что сервлет с отображением /*
будет выбран до любого сервлета с расширением (например, *.html
), тогда как сервлет с отображением /
будет выбранные только после сопоставлений с расширениями (и будут использоваться для любого запроса, который не соответствует чему-либо еще - это «сервлет по умолчанию»).
В частности, отображение /*
будет всегда выбирается перед отображением /
. Предотвращение любых запросов от получения собственного сервлета по умолчанию.
Либо будут выбраны только после сопоставлений сервлетов, которые являются точными совпадениями (например, /foo/bar
), и теми, которые являются сопоставлениями пути дольше, чем /*
( как /foo/*
). Обратите внимание, что пустым сопоставлением строк является точное соответствие для корня контекста (http://host:port/context/
).
См. Главу 12 спецификации сервлета Java, доступную в версии 3.1 на странице http: // download. oracle.com/otndocs/jcp/servlet-3_1-fr-eval-spec/index.html.
Я хотел бы дополнить ответ BalusC правилами сопоставления и примером.
Правила сопоставления из спецификации Servlet 2.5:
В нашем примере есть три сервлета. / является установленным нами сервлетом по умолчанию. Tomcat устанавливает два сервлета для обслуживания jsp и jspx. Итак, чтобы отобразить http://host:port/context/hello
Для отображения http://host:port/context/hello.jsp
/**
? – Sajib Acharya 23 February 2016 в 20:46