«1. Обзор

Jersey — это платформа с открытым исходным кодом для разработки веб-сервисов RESTFul.

Помимо эталонной реализации JAX-RS, он также включает в себя ряд расширений для дальнейшего упрощения разработки веб-приложений.

В этом руководстве мы создадим небольшой пример приложения, использующего расширение Model-View-Controller (MVC), предлагаемое Jersey.

Чтобы узнать, как создать API с помощью Джерси, ознакомьтесь с этой статьей здесь.

2. MVC в Джерси

Джерси содержит расширение для поддержки шаблона проектирования 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. Настройка сервера

Чтобы использовать поддержку шаблонов MVC Jersey в нашем приложении, нам необходимо зарегистрировать определенные функции JAX-RS, предоставляемые модулями MVC.

Имея это в виду, мы определяем пользовательскую конфигурацию ресурса:

public class ViewApplicationConfig extends ResourceConfig {    
    public ViewApplicationConfig() {
        packages("com.baeldung.jersey.server");
        property(FreemarkerMvcFeature.TEMPLATE_BASE_PATH, "templates/freemarker");
        register(FreemarkerMvcFeature.class);;
    }
}

В приведенном выше примере мы настраиваем три элемента:

    Во-первых, мы используем метод packages, чтобы сообщить Джерси о необходимости сканирования файла com.baeldung. Пакет 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.baeldung.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. Вуаля, отображается страница «Welcome Fruit Index Page!».

4. Шаблоны MVC

В Джерси API MVC состоит из двух классов для привязки модели к представлению, а именно 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\u003cString, Object\u003e. Это передается непосредственно в шаблон all.ftl, который просто отображает наш список фруктов.

4.3. Обработка ошибок с помощью MVC

@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:

Вообще говоря, цель аннотации @ErrorTemplate — привязать модель к представлению ошибок. Этот обработчик ошибок позаботится о рендеринге ответа, когда во время обработки запроса возникнет исключение.

В нашем простом примере Fruit API, если во время обработки не возникает ошибок, для рендеринга страницы используется шаблон named.ftl. В противном случае, если возникнет исключение, пользователю будет показан шаблон error.ftl.

В этом случае модель сама является выброшенным исключением. Это означает, что внутри нашего шаблона мы можем вызывать методы непосредственно для объекта исключения.

<body>
    <h1>Error - ${model.message}!</h1>
</body>

Давайте быстро взглянем на фрагмент из нашего шаблона error.ftl, чтобы выделить это:

@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 и способы обработки ошибок.