Как развернуть приложение JAX-RS?
Спецификация JAX-RS 1.1 говорит на странице 6:
Если подкласса Application нет, добавленный сервлет ДОЛЖЕН иметь имя:
javax.ws.rs.core.Application
Что такое добавленный сервлет? Это может быть произвольный сервлет?
Если имеется подкласс Application, и уже существует определенный сервлет, имеющий параметр инициализации сервлета с именем:
javax.ws.rs.Application
Опять же, что здесь за сервлет?
Если имеется подкласс Application, который не обрабатывается существующим сервлетом, то сервлет, добавленный ContainerInitializer, ДОЛЖЕН быть назван с полным именем подкласса Application.
Означает ли "сервлет, добавленный ContainerInitializer", что сервлеты добавляются автоматически? Как будет выглядеть конфигурация?
На данный момент я не использую ни класс Application, ни web.xml, и он работает (с GlassFish 3.1). Требуется ли для этого механизма развертывания полное сканирование пути класса, которое может быть медленным с большими библиотеками?
Как развернуть на контейнере сервлетов?
В Интернете существует множество вариантов конфигурации. Посмотрите этот пример с контекстными параметрами в web.xml (у меня не работает!). Каков предпочтительный способ развертывания приложения JAX-RS?
4 ответа
Существует несколько вариантов развертывания в контейнере Java EE 6 (более конкретно, реализация Servlet 3.0):
Самое простое это:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_3_0.xsd" version="3.0">
<servlet>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
Тогда все @Path
а также @Provider
классы, найденные в вашем веб-приложении, будут доступны в приложении JAX-RS "по умолчанию" с шаблоном URL сервлета "/rest/*"
,
Если у вас есть один или несколько классов, которые расширяются javax.ws.rs.core.Application
, вы можете указать так:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_3_0.xsd" version="3.0">
<servlet>
<servlet-name>com.example.jaxrs.MyApplication</servlet-name>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>com.example.jaxrs.MyApplication</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
Вы можете сделать это, если хотите вернуть только определенные наборы @Path
/@Provider
классы на URL (чтобы вы могли иметь второй MyApplication2 с другим шаблоном URL выше).
Вы также можете пропустить весь web.xml
в целом и просто аннотировать ваш MyApplication
класс с @ApplicationPath
который будет служить шаблоном URL. Я бы порекомендовал сохранить web.xml
в любом случае, потому что вам, вероятно, придется все равно добавить туда другую информацию о веб-приложении.
Если вам интересно, где servlet-class
происходит, он автоматически добавляется средой. Вы можете получить представление, посмотрев на сервлет 3.0 ServletContext
,
В WAS 8.5 я изменяю web.xml, чтобы добавить:
<servlet>
<servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.tada.rest.RestApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Мои RestApplication выглядят так:
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
public class RestApplication extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> sets = new HashSet<Class<?>>();
sets.add(RestService.class);
return sets;
}
}
Мой RestService выглядит так
@Path("/tada")
public class RestService {
@GET
public String getSomething() {
return "tada";
}
}
И я добавляю в pom.xml зависимость:
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0</version>
</dependency>
С Servlet3.0, следуйте этому. Это работает для меня.
<servlet>
<description>JAX-RS Tools Generated - Do not modify</description>
<servlet-name>JAX-RS Servlet</servlet-name>
<servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>your.restsrv.config.RESTConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<enabled>true</enabled>
<async-supported>false</async-supported>
</servlet>
<servlet>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>JAX-RS Servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
Как я уже сказал в комментарии выше, все зависит от структуры, которую вы хотите использовать.
http://syrupsucker.blogspot.com/2008/10/deploying-jersey-in-tomcat-60.html для Джерси http://syrupsucker.blogspot.com/2008/10/deploying-resteasy-in-tomcat-60.html для RESTeasy
Насколько я знаю, JAX-RS не содержит спецификации для развертывания.