The Top 5 New Features in Java EE 8
Java EE 8 brings with it a lot of goodness, so let's take a look at the top five of these new features!
Join the DZone community and get the full member experience.
Join For FreeThe much-anticipated release of Java Enterprise Edition 8 boasts two exciting new APIs (JSON-Binding 1.0 and Java EE Security 1.0) and improvements to current APIs (JAX-RS 2.1, Bean Validation 2.0, JSF 2.3, CDI 2.0, JSON-P 1.1, JPA 2.2, and Servlet 4.0). This is the first release of Oracle's enterprise Java platform for nearly four years and it contains hundreds of new features, updated functionality, and bug fixes.
So, what are the best new features? I attempt to answer this highly subjective question in this post.
Top 5 New Features TL;DR
- The new Security API: Annotation-driven authentication mechanism. The brand new Security API, which contains three excellent new feature: an identity store abstraction, a new security context, and a new annotation-driven authentication mechanism that makes web.xml file declarations obsolete. This last one is what I'll be talking about today.
- JAX-RS 2.1: New reactive client. The new reactive client in JAX-RS 2.1, which embraces the reactive programming style and allows the combination of endpoint results.
- The new JSON Binding API. The new JSON-binding API, which provides a native Java EE solution to JSON serialization and deserialization.
- CDI 2.0: Use in Java SE. This interesting new feature in CDI 2.0 allows bootstrapping of CDI in Java SE application.
- Servlet 4.0: Server Push. This server push feature in Servlet 4.0 aligns the servlet specification with HTTP/2.
You might be interested in the new book Java EE 8: Only What's New for just $9.95. It covers all additions to Java EE 8 with plenty of code examples.
Are you ready? So let's get to it.
1. The New Security API
Probably, the single most significant new feature added to Java EE 8 is the new security API.
The primary motivations for this new API were to simplify, standardize and modernize the way security concerns are handled across containers and implementations. And they have done a great job.
- The configuration of web authentication has been modernized thanks to three new annotations that make web.xml file declaration redundant. More on this later.
- The new security context API standardizes the way the servlet and EJB container perform authentication.
- The new Identity store abstraction to simplifies the use of identity stores.
So let's look at the first of these additions.
Annotation-Driven Authentication Mechanism
This feature is all about configuring web security. Which traditional required XML declaration in the web.xml file.
This is no longer necessary, thanks to the HttpAuthenticationMechanism
interface, which represents an HTTP authentication and comes with three built-in CDI-enabled implementations, each representing one of the three ways web security can be configured.
They are trigger with the use of one of these annotations.
@BasicAuthenticationMechanismDefinition
@FormAuthenticationMechanismDefinition
@CustomFormAuthenticationMechanismDefinition
They replicate the functionality of the classic HTTP basic authentication, form, and custom form-based authentication already available in the servlet container.
For example, to enable Basic authentication, all that is necessary is to add the BasicAuthenticationMechanismDefinition
annotation to your servlet and that's it.
@BasicAuthenticationMechanismDefinition(realmName="${'user-realm'}")
@WebServlet("/user")
@DeclareRoles({ "admin", "user", "demo" })
@ServletSecurity(@HttpConstraint(rolesAllowed = "user"))
public class UserServlet extends HttpServlet { ... }
You can now throw away your XML configurations and use one of these new annotations to drive web security.
2. JAX-RS 2.1: New Reactive Client
Let's look at the new reactive client in JAX-RS 2.1 and how it embraces the reactive programming style.
The reactive approach is centered on the idea of data flows with an execution model that propagates changes through the flow. A typical example would be a JAX-RS method call. When the call returns, the next action is performed on the result of the method call (which might be a continuation, completion, or error).
You can think of it as data being an asynchronous pipeline of processes with the next process acting on the result of the previous process and then pass the result of its process to the next one in the chain. The flow of composable so you can compose and transform many flows into the one result.
The reactive feature is enabled by calling the method on an instance of the rx()Invocation.Builder
used to construct client instances. Its return type is a CompletionStage
with the parameterized Response
type. The CompletionStage
interface was introduced in Java 8 and suggests some interesting possibilities.
For example, in this code snippet, two calls are made to different endpoints and the results are then combined:
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. The New JSON Binding API
Now, let's move on to the next great feature. The new JSON Binding API provides a native Java EE solution to JSON serialization and deserialization.
Previously, if you wanted to serialize and deserialize Java to and from JSON, you would have to rely on third-party APIs like Jackson or GSON. Not anymore. With the new JSON Binding API, you have all the feature you could possibly want natively available.
It couldn't be simpler to generate a JSON document from a Java object. Just call the toJson()
method and pass it the instance you want to serialize.
String bookJson = JsonbBuilder.create().toJson(book);
And it is just as simple to deserialize a JSON document to a Java object. Just pass the JSON document and target class to the fromJson()
method and out pops your Java object.
Book book = JsonbBuilder.create().fromJson(bookJson, Book.class);
But that's not all.
Behavior Customization
It's possible to customize the default serialization and deserialization behavior by annotating fields, JavaBeans methods, and classes.
For example, you could use the @JsonbNillable
to customize null handling and @JsonbPropertyOrder
annotations to customize property order, which you specify at the class level. You could specify the number format with the @JsonbNumberFormat()
annotation and change the name of a field with the @JsonbProperty()
annotation.
@JsonbNillable
@JsonbPropertyOrder(PropertyOrderStrategy.REVERSE)
public class Booklet {
@JsonbProperty("cost")
@JsonbNumberFormat("#0.00")
private Float price;
}
Alternatively, you could choose to handle customization with the runtime configuration builder, JsonbConfig
:
JsonbConfig jsonbConfig = new JsonbConfig()
.withPropertyNamingStrategy( PropertyNamingStrategy.LOWER_CASE_WITH_DASHES)
.withNullValues(true)
.withFormatting(true);
Jsonb jsonb = JsonbBuilder.create(jsonbConfig);
Either way, the JSON Binding API provides extensive capabilities for the serialization and deserialization of Java objects.
4. CDI 2.0: Use in Java SE
Now let's move on to the next API. The CDI 2.0 API. This version boasts many new features and one of the more interesting features is the capability to bootstrap CDI in Java SE applications.
To use CDI in Java SE the CDI container must be explicitly bootstrapped. This is achieved by calling the static method newInstance()
on the SeContainerInitializer
abstract class. It returns an SeContainer
instance that is a handle to the CDI runtime, with which you can do CDI resolution as shown in this code snippet. It has access to the BeanManager, which is the core entry point to CDI.
SeContainer seContainer =
SeContainerInitializer.newInstance().initialize();
Greeting greeting = seContainer.select(Greeting.class).get();
greeting.printMessage("Hello World");
seContainer.close();
The CDI bean is retrieved with the select()
method by passing it the class name of the bean you want to retrieve and use.
Configuration Options
Further configurations can be made to the SeContext
by adding interceptors, extensions, alternatives, properties, and decorators.
.enableInterceptors()
.addExtensions()
.selectAlternatives()
.setProperties()
.enableDecorators()
The container is manually shut down by calling the close()
method on SeContainer
or automatically when using a try-with-resources structure because SeContainer
extends the AutoCloseable
interface.
5. Servlet 4.0: Server Push
And last, but not least, the Server Push feature in Servlet 4.0 which aligns the servlet specification with HTTP/2.
To understand this feature, you first need to know what server push is.
What Is Server Push?
Server push is one of the many new features in the HTTP/2 protocol and is designed to anticipate client-side resource requirements by pushing those resources into the browser's cache so that when the client sends a request for a webpage and receives a response back from the server, the resources it needs are already in the cache. This is a performance-enhancing feature that improves the speed that web pages load.
How Is It Exposed in Servlet 4.0?
In Servlet 4.0, the Server Push feature is exposed via a PushBuilder
instance, which is obtained from an HttpServletRequest
instance.
Take a look at this code snippet. You can see that the path to the header.png is set on the PushBuilder
instance via the path()
method and pushed to the client by calling push()
. When the method returns, the path and conditional headers are cleared in readiness for the builder's reuse. The menu.css file is pushed and then the ajax.js JavaScript file is pushed to the client.
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
}
By the time the Servlet doGet()
method finishes executing, the resource will have arrived at the browser. The HTML generated from the JSP, that requires these resources, will not need to request them from the server as they will already be browsers cache.
Published at DZone with permission of Alex Theedom, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments