Ответ 1
Из Servlet 3.0 спецификация, вот как веб-контейнер должен найти сервлет после получения запроса (выделение мое):
Путь, используемый для сопоставления сервлету, - это URL-адрес запроса от объект запроса минус путь контекста и параметры пути. Ниже приведены правила сопоставления URL-адресов. Первый успешный матч используется без каких-либо последующих попыток:
- Контейнер попытается найти точное соответствие пути запроса к пути сервлета. Успешный матч выбирает сервлета.
- Контейнер будет рекурсивно пытаться сопоставить самый длинный префикс пути. Это делается путем перехода вниз по дереву путей в каталог в то время, используя символ/как разделитель путей. Самый длинный match определяет выбранный сервлет.
- Если последний сегмент пути URL содержит расширение (например,.jsp), контейнер сервлета будет пытаться сопоставить сервлет, который обрабатывает запросы на расширение. Расширение определяется как часть последний сегмент после последнего. характер.
- Если ни одно из предыдущих трех правил не приводит к совпадению сервлета, контейнер будет пытаться обслуживать контент, соответствующий запрашиваемый ресурс. Если для приложение, оно будет использоваться. Многие контейнеры обеспечивают неявное сервлет по умолчанию для обслуживания содержимого.
В контейнере должны использоваться сопоставления строк с учетом регистра для соответствия.
Вы также должны посмотреть спецификацию сопоставлений (см. ниже):
В дескрипторе развертывания веб-приложения следующий синтаксис используется для определения отображений:
Строка начинается с символа
‘/’
и заканчивается суффиксом‘/*’
используется для отображения пути.Строка, начинающаяся с префикса
‘*.’
, используется как отображение расширений.Пустая строка
("")
- это специальный шаблон URL, который точно соответствует корень контекста приложения, то есть запросы формыhttp://host:port/<contextroot>/
. В этом случае информация о пути’/’
и путь сервлета и путь контекста - пустая строка("")
.Строка, содержащая только символ
’/’
, указывает на "default" сервлет приложения. В этом случае путь сервлета является запросить URI минус контекстный путь, а информация о пути - null.Все остальные строки используются только для точных совпадений
Рассмотрим теперь примеры. Рассмотрим следующий набор отображений:
Path Pattern Servlet /foo/bar/* servlet1 /baz/* servlet2 /catalog servlet3 *.bop servlet4
Следующее поведение приведет к:
Incoming Path Servlet Handling Request /foo/bar/index.html servlet1 /foo/bar/index.bop servlet1 /baz servlet2 /baz/index.html servlet2 /catalog servlet3 /catalog/index.html "default" servlet /catalog/racecar.bop servlet4 /index.bop servlet4
Обратите внимание, что в случае /catalog/index.html
и /catalog/racecar.bop
,
сервлет, отображаемый на "/catalog"
, не используется, потому что совпадение не является точным.
Теперь приступим к вашей проблеме:)
/path/test
принадлежит к пятой точке спецификации отображений. Это означает, что только пути, заканчивающиеся на /path/test
, будут нацелены на servlet1
.
Однако /path/test/*
подходит для первой точки той же спецификации. Это означает, что:
.../path/test
будет обрабатываться servlet1
и
.../path/test/abc
будет обрабатываться servlet2
Это было проверено мной в тестовом приложении.