1. Обзор
Jersey — это платформа с открытым исходным кодом для разработки веб-сервисов RESTFul .
Помимо эталонной реализации JAX-RS, он также включает в себя ряд расширений для дальнейшего упрощения разработки веб-приложений.
В этом руководстве мы создадим небольшой пример приложения, использующего расширение Model-View-Controller (MVC), предлагаемое Jersey .
Чтобы узнать, как создать API с помощью Джерси, ознакомьтесь с этой статьей здесь .
2. MVC в Джерси
Jersey содержит расширение для поддержки шаблона проектирования Model-View-Controller (MVC) .
Во-первых, в контексте компонентов Джерси контроллер из шаблона MVC соответствует классу или методу ресурса.
Точно так же представление соответствует шаблону, привязанному к классу или методу ресурсов. Наконец, модель представляет собой объект Java, возвращаемый методом ресурса (контроллером).
Чтобы использовать возможности Jersey MVC в нашем приложении, нам сначала нужно зарегистрировать расширение модуля MVC, которое мы хотим использовать .
В нашем примере мы будем использовать популярный шаблонизатор Java Freemarker . Это один из механизмов рендеринга, поддерживаемых Jersey из коробки, наряду с Mustache и стандартными Java Server Pages (JSP).
Для получения дополнительной информации о том, как работает MVC, обратитесь к этому руководству .
3. Настройка приложения
В этом разделе мы начнем с настройки необходимых зависимостей Maven в нашем файле pom.xml.
Затем мы рассмотрим, как настроить и запустить наш сервер с помощью простого встроенного сервера Grizzly .
3.1. Зависимости Maven
Начнем с добавления расширения Jersey MVC Freemarker.
Мы можем получить последнюю версию от Maven Central :
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-mvc-freemarker</artifactId>
<version>2.27</version>
</dependency>
Нам также понадобится контейнер сервлетов Grizzly.
Снова мы можем найти последнюю версию в Maven Central :
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-servlet</artifactId>
<version>2.27</version>
</dependency>
3.2. Настройка сервера
Чтобы использовать поддержку шаблонов Jersey MVC в нашем приложении , нам необходимо зарегистрировать определенные функции JAX-RS, предоставляемые модулями MVC .
Имея это в виду, мы определяем пользовательскую конфигурацию ресурса:
public class ViewApplicationConfig extends ResourceConfig {
public ViewApplicationConfig() {
packages("com.foreach.jersey.server");
property(FreemarkerMvcFeature.TEMPLATE_BASE_PATH, "templates/freemarker");
register(FreemarkerMvcFeature.class);;
}
}
В приведенном выше примере мы настраиваем три элемента:
- Во-первых, мы используем метод
packages
, чтобы указать Джерси сканировать пакетcom.foreach.jersey.server
на наличие классов, аннотированных с помощью@Path.
Это зарегистрирует нашFruitResource
- Затем мы настраиваем базовый путь для разрешения наших шаблонов. Это говорит Джерси искать в
/src/main/resources/templates/freemarker шаблоны Freemarker
. - Наконец, мы регистрируем функцию, которая обрабатывает рендеринг Freemarker, через класс
FreemarkerMvcFeature .
3.3. Запуск приложения
Теперь давайте посмотрим, как запустить наше веб-приложение. Мы будем использовать exec-maven-plugin для настройки нашего pom.xml
для выполнения нашего встроенного веб-сервера:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<configuration>
<mainClass>com.foreach.jersey.server.http.EmbeddedHttpServer</mainClass>
</configuration>
</plugin>
Давайте теперь скомпилируем и запустим наше приложение с помощью Maven:
mvn clean compile exec:java
...
Jul 28, 2018 6:21:08 PM org.glassfish.grizzly.http.server.HttpServer start
INFO: [HttpServer] Started.
Application started.
Try out http://localhost:8082/fruit
Stop the application using CTRL+C
Перейдите по URL-адресу браузера — http://localhost:8080/fruit
. Вуаля, «Добро пожаловать на страницу с фруктами!» отображается.
4. Шаблоны MVC
В Джерси MVC API состоит из двух классов для привязки модели к представлению, а именно Viewable
и @Template
.
В этом разделе мы объясним три разных способа привязки шаблонов к нашему представлению:
- Использование класса
Viewable
- Использование аннотации
@Template
- Как обрабатывать ошибки с помощью MVC и передавать их в определенный шаблон
4.1. Использование Viewable
в классе ресурсов
Начнем с Viewable
:
@Path("/fruit")
public class FruitResource {
@GET
public Viewable get() {
return new Viewable("/index.ftl", "Fruit Index Page");
}
}
В этом примере класс ресурсов FruitResource
JAX-RS является контроллером. Экземпляр Viewable
инкапсулирует модель данных, на которую ссылаются, которая представляет собой простую строку.
Кроме того, мы также включаем именованную ссылку на связанный шаблон представления — index.ftl
.
4.2. Использование @Template
в методе ресурса
Нет необходимости использовать Viewable
каждый раз, когда мы хотим привязать модель к шаблону .
В следующем примере мы просто аннотируем наш ресурсный метод с помощью @Template
:
@GET
@Template(name = "/all.ftl")
@Path("/all")
@Produces(MediaType.TEXT_HTML)
public Map<String, Object> getAllFruit() {
List<Fruit> fruits = new ArrayList<>();
fruits.add(new Fruit("banana", "yellow"));
fruits.add(new Fruit("apple", "red"));
fruits.add(new Fruit("kiwi", "green"));
Map<String, Object> model = new HashMap<>();
model.put("items", fruits);
return model;
}
В этом примере мы использовали аннотацию @Template
. Это позволяет избежать переноса нашей модели непосредственно в ссылку на шаблон через Viewable
и делает наш метод ресурса более читабельным.
Теперь модель представлена возвращаемым значением нашего метода аннотированных ресурсов — Map<String, Object>.
Это передается непосредственно в шаблон all.ftl
, который просто отображает наш список фруктов.
4.3. Обработка ошибок с помощью MVC
Теперь давайте посмотрим, как обрабатывать ошибки с помощью аннотации @ErrorTemplate
:
@GET
@ErrorTemplate(name = "/error.ftl")
@Template(name = "/named.ftl")
@Path("{name}")
@Produces(MediaType.TEXT_HTML)
public String getFruitByName(@PathParam("name") String name) {
if (!"banana".equalsIgnoreCase(name)) {
throw new IllegalArgumentException("Fruit not found: " + name);
}
return name;
}
Вообще говоря, цель аннотации @ErrorTemplate
— связать модель с представлением ошибок. Этот обработчик ошибок позаботится о рендеринге ответа, когда во время обработки запроса возникнет исключение.
В нашем простом примере Fruit API, если во время обработки не возникает ошибок , для рендеринга страницы используется шаблон named.ftl .
В противном случае, если возникнет исключение, пользователю будет показан шаблон error.ftl .
В этом случае модель сама является выброшенным исключением. Это означает, что внутри нашего шаблона мы можем вызывать методы непосредственно для объекта исключения.
Давайте быстро взглянем на фрагмент из нашего шаблона error.ftl
, чтобы выделить это:
<body>
<h1>Error - ${model.message}!</h1>
</body>
В нашем последнем примере мы рассмотрим простой модульный тест:
@Test
public void givenGetFruitByName_whenFruitUnknown_thenErrorTemplateInvoked() {
String response = target("/fruit/orange").request()
.get(String.class);
assertThat(response, containsString("Error - Fruit not found: orange!"));
}
В приведенном выше примере мы используем ответ нашего фруктового ресурса. Мы проверяем, что ответ содержит сообщение от созданного исключения IllegalArgumentException
.
5. Вывод
В этой статье мы рассмотрели расширение MVC фреймворка Jersey.
Мы начали с того, что рассказали, как MVC работает в Джерси. Далее мы рассмотрели, как настроить, запустить и настроить пример веб-приложения.
Наконец, мы рассмотрели три способа использования шаблонов MVC с Jersey и Freemarker и способы обработки ошибок.
Как всегда, полный исходный код статьи доступен на GitHub .