Статьи

Шаблоны URL в Джерси более гибкие, чем в Web.xml

Основное правило. Избегайте использования {переменных} в качестве первого пути @Path на Джерси.

Я работаю над Arena PUJ Project , RESTful веб-сервисом для поддержки соревнований PUJ. Мы находимся на ранних стадиях проекта, но уже опубликовали некоторые ресурсы в Интернете. Позвольте мне показать вам несколько примеров URL:

  1. Небезопасный метод GET для чтения всех соревнований, продвигаемых JUG:

    GET / {Competition_id} / домашнее задание

    Пример URL: http://fgaucho.dyndns.org:8080/arena-http/institution/cejug/competition

    curl -v -H «Принять: application / json» -XGET http://fgaucho.dyndns.org:8080/arena-http/institution/cejug/competition

  2. Небезопасный метод GET для чтения всех домашних заданий с названия конкурса:

    GET / {Competition_id} / домашнее задание

    Пример URL: http://fgaucho.dyndns.org:8080/arena-http/PUJCE-08/homework

    curl -v -H «Принять: application / json» -XGET http://fgaucho.dyndns.org:8080/arena-http/PUJCE-08/homework

  3. Безопасный метод для создания новой домашней работы. В бизнес-модели PUJ только профессора могут представить домашнее задание.

    POST / {Competition_id} / домашнее задание / {homework_id}

    Пример URL: http://fgaucho.dyndns.org:8080/arena-http/PUJCE-08/homework/newHomework

    curl -v -H «Принять: application / json» -XPOST http://fgaucho.dyndns.org:8080/arena-http/PUJCE-08/homework/newHomework

Проблема: вы не можете отобразить переменные в начале пути в web.xml

В Джерси все вышеуказанные URL-адреса действительны, фактически Джерси может также использовать регулярные выражения для сопоставления URL-адресов с ресурсами. Классная функция, которая теряет свою красоту в файле web.xml.

Посмотрите на третий пример, это URL, который начинается с переменной, в Джерси он объявлен так:

 

@Path("{puj}/homework") <-- Avoid to use {variables} as the first path of a resource
public class PujHomeworkResource {
@POST
@Produces( { MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("{acronym}")
public PujHomeworkEntity create(@PathParam("puj") String name, @PathParam("acronym") String acronym) {
// click here to see the full code.


И простая проблема: web.xml не поддерживает динамические шаблоны так же, как Джерси. Таким образом, вы просто не можете объявить URL-шаблон как / * / homework / *:

    <security-constraint>
<display-name>Restrict advertisement pages to
customers</display-name>
<web-resource-collection>
<web-resource-name>To create Homework is privileged to Professors</web-resource-name>
<description />
<url-pattern><font color="red">/*/homework/*</font></url-pattern> <font color="red"><strong><-- <em>This is valid but useless :(</em></strong></font>
<http-method>POST</http-method>
<http-method>GET</http-method>
</web-resource-collection>
<auth-constraint>
<description>PUJ Homeworks.</description>
<role-name>professor</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>

Такой шаблон URL / * / homework / * не будет отображать URL-адреса, такие как / PUJCE-09 / homework или / GOJAVA-09 / homework. Все еще возможно использовать переменные из Джерси, но это потребовало бы статического отображения для каждого возможного значения в файле web.xml — бесполезно.

обходные

Я не вижу ничего другого, кроме как реорганизовать мой код и включить статический путь в начало моих URL. Альтернативой, предложенной доктором Хэдли, является использование @RolesAllowedаннотация, что может решить проблему, но в конечном итоге создает другую проблему (IMO). Если вы объявляете безопасность своего приложения аннотациями, вам нужно перекомпилировать и повторно развертывать все приложение при каждом обновлении ограничений безопасности. Если вы заранее знаете, что ваше приложение будет редко обновляться, хорошо — продолжайте и используйте аннотации. На данный момент я не вижу другой альтернативы, кроме рефакторинга моего кода, чтобы включить статические имена в начало всех путей. После того, как я закончу эту задачу, я продолжу свою поездку в REST и, возможно, вернусь сюда с более подробной информацией. Я включил некоторые ссылки ниже на случай, если вы ищете, что спецификации говорят об этом ?

Отображения в спецификации Servlet 2.5

Из раздела 11.2 Спецификации Servlet 2.5 вы читаете:

  • В дескрипторе развертывания веб-приложения для определения отображений используется следующий синтаксис:

    • Строка, начинающаяся с символа ‘/’ и заканчивающаяся суффиксом ‘/ *’, используется для отображения пути.

    • Строка, начинающаяся с ‘*.’ Префикс используется как отображение расширения.

    • Строка, содержащая только символ «/», обозначает сервлет «по умолчанию» приложения. В этом случае путь сервлета является URI запроса минус путь контекста, а информация о пути равна нулю.

    • Все остальные строки используются только для точных совпадений.

Отображения в спецификации JAX-RS 1.0

Jersey — эталонная реализация спецификации 1.0 JAX-RS, и способ определения шаблонов URL немного отличается от спецификации сервлета. В разделе 3.4 спецификации JAX-RS 1.0 вы читаете:

  • Корневой класс ресурсов привязывается к пространству URI с помощью аннотации @Path. Значение аннотации — это 23 шаблона относительного пути URI, базовый URI которого предоставляется контекстом развертывания. 24 Шаблон пути URI — это строка с нулевым или большим количеством встроенных параметров, которая, когда значения заменяются 25 для всех параметров, является допустимым путем URI . Javadoc для аннотации @Path описывает их синтаксис.

    В Джавадоке Джерси вы читаете:

    • Параметры встроенного шаблона допускаются и имеют вид:

       

      param = "{" *WSP name *WSP [ ":" *WSP regex *WSP ] "}"
      name = (ALPHA / DIGIT / "_")*(ALPHA / DIGIT / "." / "_" / "-" ) ; \w[\w\.-]*
      regex = *( nonbrace / "{" *nonbrace "}" ) ; where nonbrace is any char other than "{" and "}

      « См. RFC 5234 для описания синтаксиса, использованного выше, и расширений WSP, ALPHA и DIGIT. В приведенном выше имени указано имя параметра шаблона, а необязательное регулярное выражение задает содержимое группы захвата для параметра. Если регулярное выражение не установлено при условии, что используется значение по умолчанию [^ /] +, которое заканчивается на границе сегмента пути. Сопоставление URI запроса с шаблонами URI выполняется для закодированных значений пути, и реализации не будут автоматически избегать литеральных символов в регулярном выражении, поэтому любые литералы в regex должен быть исключен автором в соответствии с правилами RFC 3986, раздел 3.3., При использовании регулярных выражений рекомендуется соблюдать осторожность, неправильное использование может привести к тому, что параметр шаблона совпадет с неожиданными путями URI. См. Pattern для получения дополнительной информации о синтаксисе регулярных выражений. Значения параметров шаблона могут быть извлечены с использованием PathParam. Литеральная часть предоставленного значения (те символы, которые не являются частью параметра шаблона) автоматически кодируется в процентах, чтобы соответствовать пути производства в разделе 3.3 RFC 3986 . Обратите внимание, что процентные значения в буквальной части значения допускаются, реализация распознает такие значения и не будет дважды кодировать символ « % ».

От http://weblogs.java.net/blog/felipegaucho