Статьи

Топ 5 новых функций в Java EE 8

Долгожданный выпуск Java Enterprise Edition 8 может похвастаться двумя потрясающими новыми API (JSON-Binding 1.0 и Java EE Security 1.0) и улучшениями текущих API (JAX-RS 2.1, Bean Validation 2.0, JSF 2.3, CDI 2.0, JSON-P). 1.1, JPA 2.2 и Servlet 4.0). Это первый выпуск корпоративной Java-платформы Oracle за последние почти четыре года. Он содержит сотни новых функций, обновленных функций и исправлений ошибок. Итак, каковы лучшие новые функции? Я пытаюсь ответить на этот весьма субъективный вопрос в этом посте.

Топ 5 новых функций TL; DR

  1. Новый API безопасности: механизм аутентификации на основе аннотаций
    Совершенно новый API безопасности, который содержит три отличных новых функции: абстракцию хранилища идентификаторов, новый контекст безопасности и новый механизм аутентификации на основе аннотаций, который делает объявления файлов web.xml устаревшими. Об этом я и поговорю сегодня.
  2. JAX-RS 2.1: новый реактивный клиент
    Новый реактивный клиент в JAX-RS 2.1, который охватывает стиль реактивного программирования и позволяет комбинировать результаты конечной точки.
  3. Новый JSON Binding API
    Новый API-интерфейс JSON-привязки, обеспечивающий стандартное решение Java EE для сериализации и десериализации JSON.
  4. CDI 2.0: использование в Java SE
    Интересная новая функция в CDI 2.0 позволяет загружать CDI в приложении Java SE.
  5. Сервлет 4.0: Push-сервер
    Функция выдвижения сервера в Servlet 4.0 выравнивает спецификацию сервлета с HTTP / 2.

Вы готовы? Итак, давайте вернемся к этому.

1. Новый API безопасности

Вероятно, единственная наиболее значимая новая функция, добавленная в Java EE 8, — это новый API безопасности.

Основными мотивами для этого нового API были упрощение, стандартизация и модернизация способов решения проблем безопасности в контейнерах и реализациях. И они проделали большую работу.

Конфигурация веб-аутентификации была модернизирована благодаря трем новым аннотациям, которые делают объявление файла web.xml избыточным. Подробнее об этом позже.

Новый API контекста безопасности стандартизирует способ аутентификации сервлета и контейнера EJB и

Новая абстракция хранилища удостоверений упрощает использование хранилищ удостоверений.

Итак, давайте посмотрим на первое из этих дополнений.

Механизм аутентификации на основе аннотаций

Эта функция предназначена для настройки веб-безопасности. Какая традиционная требуется декларация XML в файле web.xml.

В этом больше нет необходимости, благодаря интерфейсу HttpAuthenticationMechanism, который представляет HTTP-аутентификацию и поставляется с тремя встроенными реализациями с поддержкой CDI, каждая из которых представляет один из трех способов настройки веб-безопасности.

Они запускаются с использованием одной из этих аннотаций.

1
2
3
@BasicAuthenticationMechanismDefinition
@FormAuthenticationMechanismDefinition
@CustomFormAuthenticationMechanismDefinition

Они дублируют функциональность классической HTTP-аутентификации, аутентификации на основе форм и пользовательских форм, уже доступной в контейнере сервлетов.

Например, чтобы включить обычную аутентификацию, все, что нужно, это добавить аннотацию BasicAuthenticationMechanismDefinition в ваш сервлет и все.

1
2
3
4
5
@BasicAuthenticationMechanismDefinition(realmName="${'user-realm'}")
@WebServlet("/user")
@DeclareRoles({ "admin", "user", "demo" })
@ServletSecurity(@HttpConstraint(rolesAllowed = "user"))
public class UserServlet extends HttpServlet { … }

Теперь вы можете выбросить свои XML-конфигурации и использовать одну из этих новых аннотаций для обеспечения веб-безопасности.

2. JAX-RS 2.1: новый реактивный клиент

Давайте рассмотрим новый реактивный клиент в JAX-RS 2.1 и то, как он охватывает стиль реактивного программирования.

Реактивный подход основан на идее потоков данных с моделью исполнения, которая распространяет изменения в потоке. Типичным примером будет вызов метода JAX-RS. Когда вызов возвращается, следующее действие выполняется над результатом вызова метода (который может быть продолжением, завершением или ошибкой).

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

Реактивная функция активируется путем вызова метода rx () для экземпляра Invocation.Builder, используемого для создания клиентских экземпляров. Тип возвращаемого значения — CompletionStage с параметризованным типом ответа . Интерфейс CompletionStage был представлен в Java 8 и предлагает некоторые интересные возможности.

Например, в этом фрагменте кода два вызова выполняются для разных конечных точек, а затем результаты объединяются:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
CompletionStage<Response> cs1 = ClientBuilder.newClient()
    .target(".../books/history")
    .request()
    .rx()
   .get();
  
 CompletionStage<Response> cs2 = ClientBuilder.newClient()
    .target(".../books/geology")
    .request()
    .rx()
   .get();
 
 cs1.thenCombine(cs2, (r1, r2) ->
  r1.readEntity(String.class) + r2.readEntity(String.class))
  .thenAccept(System.out::println);

3. Новый JSON Binding API

Теперь давайте перейдем к следующей замечательной функции. Новый API привязки JSON, этот API предоставляет решение Java EE для сериализации и десериализации JSON .

Ранее, если вы хотели сериализовать и десериализовать Java в JSON и из JSON, вы должны были полагаться на сторонние API, такие как Jackson или GSON. Уже нет. С новым JSON Binding API у вас есть все функции, которые вы, возможно, хотели бы иметь в своем роде.

Не может быть проще сгенерировать документ JSON из объекта Java. Просто вызовите метод toJson () и передайте ему экземпляр, который вы хотите сериализовать.

1
String bookJson = JsonbBuilder.create().toJson(book);

И так же просто десериализовать документ JSON в объект Java. Просто передайте документ JSON и целевой класс методу fromJson () и выскочит ваш Java-объект.

1
Book book = JsonbBuilder.create().fromJson(bookJson, Book.class);

Но это не все.

Настройка поведения

Можно настроить сериализацию и десериализацию по умолчанию, добавляя аннотации к полям, методам JavaBeans и классам.

Например, вы можете использовать @JsonbNillable для настройки обработки нуля и аннотации @JsonbPropertyOrder для настройки порядка свойств, который вы указываете на уровне класса. Вы можете указать числовой формат с помощью аннотации @JsonbNumberFormat () и изменить имя поля с помощью аннотации @JsonbProperty () .

1
2
3
4
5
6
7
8
9
@JsonbNillable
@JsonbPropertyOrder(PropertyOrderStrategy.REVERSE)
public class Booklet {
 
  @JsonbProperty("cost")
  @JsonbNumberFormat("#0.00")
  private Float price;
 
}

В качестве альтернативы вы можете выбрать настройку с помощью компоновщика конфигурации времени выполнения JsonbConfig :

1
2
3
4
5
6
JsonbConfig jsonbConfig = new JsonbConfig()
    .withPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE_WITH_DASHES)
    .withNullValues(true)
    .withFormatting(true);
 
Jsonb jsonb = JsonbBuilder.create(jsonbConfig);

В любом случае, API связывания JSON предоставляет широкие возможности для сериализации и десериализации объектов Java.

4. CDI 2.0: использование в Java SE

Теперь давайте перейдем к следующему API. API CDI 2.0. Эта версия может похвастаться множеством новых функций, и одной из наиболее интересных функций является возможность начальной загрузки CDI в приложениях Java SE .

Чтобы использовать CDI в Java SE, контейнер CDI должен быть явно загружен. Это достигается путем вызова статического метода newInstance () в абстрактном классе SeContainerInitializer . Он возвращает экземпляр SeContainer, который является дескриптором среды выполнения CDI, с помощью которой вы можете выполнить разрешение CDI, как показано в этом фрагменте кода. Он имеет доступ к BeanManager, который является основной точкой входа в CDI.

1
2
3
4
5
SeContainer seContainer =
       SeContainerInitializer.newInstance().initialize();
 Greeting greeting = seContainer.select(Greeting.class).get();
 greeting.printMessage("Hello World");
 seContainer.close();

Компонент CDI извлекается методом select () , передавая ему имя класса компонента, который вы хотите получить и использовать.

Параметры конфигурации

Дальнейшие конфигурации могут быть сделаны для SeContext путем добавления перехватчиков, расширений, альтернатив, свойств и декораторов.

1
2
3
4
5
.enableInterceptors()
.addExtensions()
.selectAlternatives()
.setProperties()
.enableDecorators()

Контейнер отключается вручную путем вызова метода close () в SeContainer или автоматически при использовании структуры try-with-resources, поскольку SeContainer расширяет интерфейс AutoCloseable .

5. Сервлет 4.0: Push-сервер

И, наконец, что не менее важно, функция Server Push в Servlet 4.0, которая выравнивает спецификацию сервлета с HTTP / 2.

Чтобы понять эту функцию, сначала нужно узнать, что такое push-запрос сервера.

Что такое сервер Push?

Push-сервер является одной из многих новых функций в протоколе HTTP / 2 и предназначен для предвидения требований к ресурсам на стороне клиента, помещая эти ресурсы в кэш браузера, чтобы клиент отправлял запрос на веб-страницу и получал ответ обратно. с сервера необходимые ему ресурсы уже находятся в кеше. Это функция повышения производительности, которая повышает скорость загрузки веб-страниц.

Как это выставлено в Servlet 4.0?

В Servlet 4.0 функция Server Push предоставляется с помощью экземпляра PushBuilder, который получен из экземпляра HttpServletRequest .

Посмотрите на этот фрагмент кода. Вы можете видеть, что путь к header.png устанавливается в экземпляре PushBuilder с помощью метода path () и передается клиенту путем вызова push () . Когда метод возвращается, путь и условные заголовки очищаются в готовности к повторному использованию компоновщика. Файл menu.css передается, а затем файл javascript ajax.js передается клиенту.

01
02
03
04
05
06
07
08
09
10
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
  
    PushBuilder pushBuilder = request.newPushBuilder();
    pushBuilder.path("images/header.png").push();
    pushBuilder.path("css/menu.css").push();
    pushBuilder.path("js/ajax.js").push();
  
    // Return JSP that requires these resources
  
}

К тому времени, как завершится выполнение метода Servlet doGet () , ресурс поступит в браузер. HTML-код, сгенерированный из JSP, для которого требуются эти ресурсы, не должен запрашивать их с сервера, поскольку они уже будут кэшироваться браузерами.

Вывод

Ну, это самое лучшее из новой функции в Java EE 8, но есть еще много возможностей, о которых можно рассказать.

Это все на данный момент.

Опубликовано на Java Code Geeks с разрешения Алекса Тидома, партнера нашей программы JCG. Смотрите оригинальную статью здесь: Топ 5 новых функций в Java EE 8

Мнения, высказанные участниками Java Code Geeks, являются их собственными.