天天看點

Java EE 8的五大新特性詳解Java EE 8的五大新特性詳解

版權聲明:本文為部落客chszs的原創文章,未經部落客允許不得轉載。 https://blog.csdn.net/chszs/article/details/79802993

Java EE 8的五大新特性詳解

  • 2018.4.3
  • 版權聲明:本文為部落客chszs的原創文章,未經部落客允許不得轉載。

Java EE 8帶來了很多新特性,其中最好的新特性有下面五個。

備受期待的Java企業版第8版(Java EE 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)。這是Oracle近四年來釋出的Java企業平台,它包含數百個新特性、更新功能和錯誤修複。

新特性TOP 5

1、Java EE Security 1.0 API

提供了注釋驅動的認證機制。這個全新的安全API包含三項出色的新功能:身份存儲抽象、新的安全上下文以及新注釋驅動的身份驗證機制(使用web.xml配置檔案進行聲明的方式過時了)。

2、JAX-RS 2.1 API

新的響應式用戶端。JAX-RS 2.1規範中定義了新型響應式用戶端,它包含響應式程式設計風格并允許端點結果的組合。

3、JSON-Binding 1.0 API

新的JSON綁定API,為JSON序列化和反序列化提供了本地Java EE解決方案。

4、CDI 2.0規範

在Java SE中使用。在CDI 2.0中有趣的新功能是允許在Java SE應用程式中引導CDI。

5、Servlet 4.0規範

Servlet 4.0支援伺服器推技術。這種推技術使得Servlet規範與HTTP/2協定保持了一緻。

新的安全API

或許Java EE 8最重要的新特性就是新的安全API。釋出這個新API的主要動機是簡化,标準化和現代化跨容器和實作處理安全問題的方式。

  • Web身份認證的配置:已經實作了現代化,這要歸功于三個使web.xml檔案聲明成為備援的新注釋。
  • 新的安全上下文:API标準化了Servlet和EJB容器執行認證的方式。
  • 新的I身份存儲抽象簡化了身份存儲的使用。

注釋驅動的認證機制

釋出了3個關于配置網絡安全的新注釋。之前傳統的方式是通過在web.xml配置檔案中進行聲明。

HttpAuthenticationMechanism接口,它代表了HTTP身份驗證,并帶有三個内置的啟用CDI的實作,每個實作代表Web安全性可配置的三種方式之一。

3個新注釋如下:

  • @BasicAuthenticationMechanismDefinition(基本身份認證機制定義)
  • @FormAuthenticationMechanismDefinition(表單身份認證機制定義)
  • @CustomFormAuthenticationMechanismDefinition(自定義表單身份認證機制定義)

例如,要啟用基本認證,所有必要的是将BasicAuthenticationMechanismDefinition 注釋添加Servlet,如下:

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

開發者可以丢棄XML配置,并使用其中一個新注釋來驅動網絡安全。

JAX-RS 2.1中的新響應式用戶端

響應式方法的核心是資料流的概念,其中執行模型通過流傳播變化。一個典型的例子是JAX-RS的方法調用。當調用傳回時,将對方法調用的結果(可能是繼續、完成或錯誤)執行下一個操作。

您可以将其視為異步流程的資料,下一個程序将處理前一個程序的結果,然後将程序的結果傳遞給鍊中的下一個程序。可組合的流程使得開發者可以将許多流程組合并轉換為一個結果。

通過調用rx()Invocation.Builder執行個體的方法來構造用戶端執行個體,啟用響應式特性。它的傳回類型是帶有參數化Response類型的CompletionStage。此CompletionStage接口在Java 8中引入,并提出了一些有趣的可能性。

例如,在這個代碼片段中,兩個調用是對不同的端點進行的,然後将結果合并:

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);
           

新的JSON綁定API

新的JSON綁定API為JSON序列化和反序列化提供了本地Java EE解決方案。

以前,如果想要對JSON進行序列化和反序列化,就必須依賴Jackson、GSON、FastJson等第三方API。現在可以使用這個新的JSON綁定API,直接使用本地可用的所有功能。

從Java對象生成JSON文檔現在非常簡單了,隻需調用toJson()方法并将它傳遞給想要序列化的執行個體即可。比如:

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

将JSON文檔反序列化為Java對象也非常簡單,隻需将JSON文檔和目标類傳遞給fromJson()方法,然後傳回Java對象。比如:

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

其中的設計哲學來自于Gson庫。但這并非全部。

行為自定義

可以通過注釋字段、JavaBean方法和類來自定義預設的序列化和反序列化行為。

例如,可以使用@JsonbNillable自定義null處理,在類級别使用@JsonbPropertyOrder注釋來自定義屬性的順序,還可以使用@JsonbNumberFormat()注釋指定數字的格式,使用@JsonbProperty()注釋來更改字段的名稱。

@JsonbNillable
@JsonbPropertyOrder(PropertyOrderStrategy.REVERSE)
public class Booklet {

    @JsonbProperty("cost")
    @JsonbNumberFormat("#0.00")
    private Float price;

}
           

或者,可以選擇使用句柄自定義JsonbConfig以便在運作時配置建構器,比如:

JsonbConfig jsonbConfig = new JsonbConfig()
                              .withPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE_WITH_DASHES)
                              .withNullValues(true)
                              .withFormatting(true);
Jsonb jsonb = JsonbBuilder.create(jsonbConfig);
           

無論使用哪種方式,JSON綁定API都為Java對象的序列化和反序列化提供了廣泛的功能。

CDI 2.0規範

在CDI 2.0 API版中擁有許多新功能,其中一個有趣的功能是在Java SE應用程式中引導CDI的功能。

要在Java SE中使用CDI,就必須明确引導CDI容器。這需要通過在SeContainerInitializer抽象類上調用靜态方法newInstance()來實作。它傳回一個SeContainer執行個體作為CDI運作時的句柄,通過該執行個體可以執行CDI解析,如下面的代碼片段所示,它可以通路BeanManager,這是CDI的核心入口點:

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

通過在select()方法中傳遞CDI Bean的類名來取回CDI Bean,以便檢索和使用。

配置選項

更多的配置可以使用SeContext通過添加攔截器、擴充、替代、屬性或裝飾器來進一步配置。

.enableInterceptors()
.addExtensions()
.selectAlternatives()
.setProperties()
.enableDecorators()
           

由于SeContainer繼承了AutoCloseable接口,故當使用try-with-resources結構時,可通過在SeContainer調用close()方法手動地或自動地關閉容器。

Servlet 4.0規範

Servlet 4.0規範中定義了伺服器推送功能,以便于HTTP/2協定保持一緻。要了解這個特性,你首先需要知道伺服器推送是什麼。

什麼是伺服器推送

伺服器推送是HTTP/2協定中的新特性之一,旨在通過将伺服器端的資源推送到浏覽器的緩存中來預測用戶端的資源需求,以便當用戶端發送網頁請求并接收來自伺服器的響應時,它需要的資源已經在緩存中。這是一項提高網頁加載速度的性能增強的功能。

如何在Servlet 4.0公開伺服器推送

在Servlet 4.0中,伺服器推送功能是通過PushBuilder執行個體公開的,此執行個體是從HttpServletRequest執行個體中擷取的。

看下面這個代碼片段,可以看到header.png的路徑是通過path()方法設定在PushBuilder執行個體上的,并通過調用push()方法被推送到用戶端。當方法傳回時,路徑和條件報頭将被清除,以便建構器重用。然後推送menu.css檔案,接着是推送ajax.js這個JavaScript檔案。

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()方法執行完畢後,資源将會到達浏覽器。從JSP生成的HTML需要這些資源,但不需要從伺服器請求它們,因為它們已經在浏覽器的緩存中。