备受期待的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)。这是Oracle企业Java平台近四年来的第一个版本,它包含数百个新功能,更新的功能和错误修复。那么最好的新功能是什么?
Web认证的配置已经实现了现代化,这要归功于三个使web.xml文件声明成为冗余的新注释。稍后再说。
新的安全上下文 API标准化了servlet和EJB容器执行身份验证的方式
新的Identity存储抽象简化了身份存储的使用。
所以我们来看看这些新增的第一个。
此功能全部是关于配置网络安全。web.xml文件中的哪个传统所需的XML声明。
由于HttpAuthenticationMechanism接口代表了HTTP身份验证,并且随附了三个内置的启用CDI的实现,这些实现代表了网络安全可以配置的三种方式之一,这已不再是必需的。
他们触发使用这些注释之一。
@BasicAuthenticationMechanismDefinition
@FormAuthenticationMechanismDefinition
@CustomFormAuthenticationMechanismDefinition
它们替换了servlet容器中已有的传统HTTP基本认证,基于表单和自定义表单的认证功能已经在servlet容器中了。
例如,要启用基本身份验证,所需做的一切就是将@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方法调用。当调用返回时,将对方法调用的结果执行下一个操作(可能是继续,完成或错误)。
您可以将其视为异步流程的流程,下一个流程将根据前一个流程的结果进行操作,然后将流程结果传递给链中的下一个流程。数据流是可组合的,因此您可以将许多流合并并转换为一个结果。
通过调用用于构造客户端实例的Invocation.Builder实例上的rx()方法来启用反应性功能。它的返回类型是具有参数化响应类型的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,此API为JSON序列化和反序列化提供了原生Java EE解决方案。
以前,如果您想要将JSON序列化和反序列化,则必须依赖Jackson或GSON等第三方API。不再。使用新的JSON绑定API,您可以使用本地可用的所有功能。
从Java对象生成JSON文档并不那么简单。只需调用toJson()方法并将它传递给想要序列化的实例即可。
String bookJson = JsonbBuilder.create().toJson(book);
可以通过注释字段,JavaBean方法和类来自定义默认的序列化和反序列化行为。
例如,您可以使用@JsonbNillable来自定义空处理和@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对象的序列化和反序列化提供了广泛的功能。
现在让我们继续看下一个API。CDI 2.0 API。该版本拥有许多新功能,其中一个更有趣的功能是在Java SE应用程序中引导CDI的功能。
要在Java SE中使用CDI,必须明确引导CDI容器。这是通过调用SeContainerInitializer抽象类的静态方法 newInstance()来实现的。它返回一个SeContainer实例,该实例是CDI运行时的句柄,您可以使用该句柄执行CDI解析,如此代码片段中所示。它可以访问作为CDI核心入口点的BeanManager。
SeContainer seContainer =
SeContainerInitializer.newInstance().initialize();
Greeting greeting = seContainer.select(Greeting.class).get();
greeting.printMessage("Hello World");
seContainer.close();
使用select()方法检索CDI bean,方法是传递要检索和使用的bean的类名称。
可以通过添加拦截器,扩展,替代方法,属性和装饰器来进一步配置SeContext。
.enableInterceptors()
.addExtensions()
.selectAlternatives()
.setProperties()
.enableDecorators()
通过在SeContainer上调用close()方法手动关闭容器,或者在使用Try -with-resources结构时自动关闭容器,因为SeContainer 扩展了AutoCloseable 接口。
最后但并非最不重要的一点是,Servlet 4.0中的服务器推送功能使servlet规范与HTTP / 2保持一致。
要理解此功能,您首先需要知道服务器推送的内容。
服务器推送是HTTP / 2协议中的许多新功能之一,旨在通过将这些资源推送到浏览器的缓存中来预测客户端资源需求,以便当客户端发送网页请求并接收到响应时从服务器,它需要的资源已经在缓存中。这是一项提高网页加载速度的性能增强功能。
在Servlet 4.0中,Server Push功能通过从HttpServletRequest实例获得的PushBuilder实例公开。
看看这段代码片段。您可以看到,通过path()方法在PushBuilder实例上设置了header.png的路径,并通过调用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不需要从服务器请求它们,因为它们已经是浏览器缓存。http://blog.xqlee.com/article/385.html