Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Java EE 8 Cookbook
Java EE 8 Cookbook

Java EE 8 Cookbook: Build reliable applications with the most robust and mature technology for enterprise development

eBook
$29.99 $43.99
Paperback
$54.99
Subscription
Free Trial
Renews at $19.99p/m

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Billing Address

Table of content icon View table of contents Preview book icon Preview Book

Java EE 8 Cookbook

New Features and Improvements

Java EE 8 is a big release, desired and anticipated by the global community for about four years. More than ever before, the whole platform is now even more robust, mature, and stable.

This chapter will cover the main APIs that we can highlight for Java EE 8. Not that they are the only topics covered by this release—far from it—but they have a big role in the enterprise context and are worthy of a careful look inside.

In this chapter, we will cover the following recipes:

  • Running your first Bean Validation 2.0 code
  • Running your first CDI 2.0 code
  • Running your first JAX-RS 2.1 code
  • Running your first JSF 2.3 code
  • Running your first JSON-P 1.1 code
  • Running your first JSON-B 1.0
  • Running your first Servlet 4.0 code
  • Running your first Security API 1.0
  • Running your first MVC 1.0 code

Running your first Bean Validation 2.0 code

Bean Validation is a Java specification that basically helps you to protect your data. Through its API, you can validate fields and parameters, express constraints using annotations, and extend your customs' validation rules.

It can be used both with Java SE and Java EE.

In this recipe, you will have a glimpse of Bean Validation 2.0. It doesn't matter whether you are new to it or already using version 1.1; this content will help you get familiar with some of its new features.

Getting ready

First, you need to add the right Bean Validation dependency to your project, as follows:

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.8.Final</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>3.0.1-b10</version>
</dependency>
</dependencies>

How to do it...

  1. First, we need to create an object with some fields to be validated:
public class User {

@NotBlank
private String name;

@Email
private String email;

@NotEmpty
private List<@PositiveOrZero Integer> profileId;

public User(String name, String email, List<Integer> profileId) {
this.name = name;
this.email = email;
this.profileId = profileId;
}
}
  1. Then we create a test class to validate those constraints:
public class UserTest {

private static Validator validator;

@BeforeClass
public static void setUpClass() {
validator = Validation.buildDefaultValidatorFactory()
.getValidator();
}

@Test
public void validUser() {
User user = new User(
"elder",
"[email protected]",
asList(1,2));

Set<ConstraintViolation<User>> cv = validator
.validate(user);
assertTrue(cv.isEmpty());
}

@Test
public void invalidName() {
User user = new User(
"",
"[email protected]",
asList(1,2));

Set<ConstraintViolation<User>> cv = validator
.validate(user);
assertEquals(1, cv.size());
}

@Test
public void invalidEmail() {
User user = new User(
"elder",
"elder-eldermoraes_com",
asList(1,2));

Set<ConstraintViolation<User>> cv = validator
.validate(user);
assertEquals(1, cv.size());
}

@Test
public void invalidId() {
User user = new User(
"elder",
"[email protected]",
asList(-1,-2,1,2));

Set<ConstraintViolation<User>> cv = validator
.validate(user);
assertEquals(2, cv.size());
}
}

How it works...

Our User class uses three of the new constraints introduced by Bean Validation 2.0:

  • @NotBlank: Assures that the value is not null, empty, or an empty string (it trims the value before evaluation, to make sure there aren't spaces).
  • @Email: Allows only a valid email format. Forget those crazy JavaScript functions!
  • @NotEmpty: Ensures that a list has at least one item.
  • @PositiveOrZero: Guarantees that a number is equal or greater than zero.

Then we create a test class (using JUnit) to test our validations. It first instantiates Validator:

@BeforeClass
public static void setUpClass() {
validator = Validation.buildDefaultValidatorFactory().getValidator();
}

Validator is an API that validates beans according to the constraints defined for them.

Our first test method tests a valid user, which is a User object that has:

  • Name not empty
  • Valid email
  • profileId list only with integers greater than zero:
User user = new User(
"elder",
"[email protected]",
asList(1,2));

And finally, the validation:

Set<ConstraintViolation<User>> cv = validator.validate(user);

The validate() method from Validator returns a set of constraint violations found, if any, or an empty set if there are no violations at all.

So, for a valid user it should return an empty set:

assertTrue(cv.isEmpty());

And the other methods work with variations around this model:

  • invalidName(): Uses an empty name
  • invalidEmail(): Uses a malformed email
  • invalidId(): Adds some negative numbers to the list

Note that the invalidId() method adds two negative numbers to the list:

asList(-1,-2,1,2));

So, we expect two constraint violations:

assertEquals(2, cv.size());

In other words, Validator checks not only the constraints violated, but how many times they are violated.

See also

Running your first CDI 2.0 code

Context and Dependency Injection (CDI) is certainly one of the most important APIs for the Java EE platform. In version 2.0, it also works with Java SE.

Nowadays, CDI has an impact on many other APIs in the Java EE platform. As said in an interview for Java EE 8 – The Next Frontier project:

"If there was CDI by the time we created JSF, it would be made completely different."
– Ed Burns, JSF Spec Lead

There is a lot of new features in CDI 2.0. This recipe will cover Observer Ordering to give you a quick start.

Getting ready

First, you need to add the right CDI 2.0 dependency to your project. To make things easier at this point, we are going to use CDI SE, the dependency that allows you to use CDI without a Java EE server:

<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se-shaded</artifactId>
<version>3.0.0.Final</version>
</dependency>

How to do it...

This recipe will show you one of the main features introduced by CDI 2.0: Ordered Observers. Now, you can turn the observers job into something predictable:

  1. First, let's make an event to be observed:
public class MyEvent {

private final String value;

public MyEvent(String value){
this.value = value;
}

public String getValue(){
return value;
}
}
  1. Now, we build our observers and the server that will fire them:
public class OrderedObserver {

public static void main(String[] args){
try(SeContainer container =
SeContainerInitializer.newInstance().initialize()){
container
.getBeanManager()
.fireEvent(new MyEvent("event: " +
System.currentTimeMillis()));
}
}

public void thisEventBefore(
@Observes @Priority(Interceptor.Priority
.APPLICATION - 200)
MyEvent event){

System.out.println("thisEventBefore: " + event.getValue());
}

public void thisEventAfter(
@Observes @Priority(Interceptor.Priority
.APPLICATION + 200)
MyEvent event){

System.out.println("thisEventAfter: " + event.getValue());
}
}

Also, don't forget to add the beans.xml file into the META-INF folder:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="all">
</beans>
  1. Once you run it, you should see a result like this:
INFO: WELD-ENV-002003: Weld SE container 
353db40d-e670-431d-b7be-4275b1813782 initialized

thisEventBefore: event -> 1501818268764
thisEventAfter: event -> 1501818268764

How it works...

First, we are building a server to manage our event and observers:

public static void main(String[] args){
try(SeContainer container =
SeContainerInitializer.newInstance().initialize()){
container
.getBeanManager()
.fireEvent(new ExampleEvent("event: "
+ System.currentTimeMillis()));
}
}

This will give us all the resources needed to run the recipe as if it was a Java EE server.

Then we build an observer:

public void thisEventBefore(
@Observes @Priority(Interceptor.Priority.APPLICATION - 200)
MyEvent event){

System.out.println("thisEventBefore: " + event.getValue());
}

So, we have three important topics:

  • @Observes: This annotation is used to tell the server that it needs to watch the events fired with MyEvent
  • @Priority: This annotation informs in which priority order this observer needs to run; it receives an int parameter, and the execution order is ascendant
  • MyEvent event: The event being observed

On the thisEventBefore method and thisEventAfter, we only changed the @Priority value and the server took care of running it in the right order.

There's more...

The behavior would be exactly the same in a Java EE 8 server. You just wouldn't need SeContainerInitializer and would need to change the dependencies to the following:

<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>

See also

Running your first JAX-RS 2.1 code

JAX-RS is an API designed to give a portable and standard way for building RESTful web services in Java. This is one of the most used technologies for data transporting between different applications that uses some network (internet included) for communication.

One of the coolest features introduced by the 2.1 release is Server-Sent Events (SSE), which will be covered in this recipe. SSE is a specification created by HTML5 where it has established a channel between server and client, one way only from server to client. It is a protocol that transports a message containing some data.

Getting ready

Let's start by adding the right dependency to our project:

    <dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-http</artifactId>
<version>2.26-b09</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>2.26-b09</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-sse</artifactId>
<version>2.26-b09</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
</dependencies>

You surely noticed that we are using Jersey here. Why? Because Jersey is the reference implementation for JAX-RS, which means that all JAX-RS specifications are first implemented through Jersey.

Moreover, with Jersey we can use Grizzly to start a small local server, which will be useful for this recipe, as we need just a few server features to show the SSE behavior.

Further on in this book, we will use a full GlassFish to build more JAX-RS recipes.

How to do it...

  1. First, we create a class that will be our server:
public class ServerMock {

public static final URI CONTEXT =
URI.create("http://localhost:8080/");
public static final String BASE_PATH = "ssevents";

public static void main(String[] args) {
try {
final ResourceConfig resourceConfig = new
ResourceConfig(SseResource.class);

final HttpServer server =
GrizzlyHttpServerFactory.createHttpServer(CONTEXT,
resourceConfig, false);
server.start();

System.out.println(String.format("Mock Server started
at %s%s", CONTEXT, BASE_PATH));

Thread.currentThread().join();
} catch (IOException | InterruptedException ex) {
System.out.println(ex.getMessage());
}
}
}
  1. Then, we create a JAX-RS endpoint to send the events to the clients:
@Path(ServerMock.BASE_PATH)
public class SseResource {

private static volatile SseEventSink SINK = null;

@GET
@Produces(MediaType.SERVER_SENT_EVENTS)
public void getMessageQueue(@Context SseEventSink sink) {
SseResource.SINK = sink;
}

@POST
public void addMessage(final String message, @Context Sse sse)
throws IOException {
if (SINK != null) {
SINK.send(sse.newEventBuilder()
.name("sse-message")
.id(String.valueOf(System.currentTimeMillis()))
.data(String.class, message)
.comment("")
.build());
}
}
}
  1. Then, we create a client class to consume the events generated from the server:
public class ClientConsumer {

public static final Client CLIENT = ClientBuilder.newClient();
public static final WebTarget WEB_TARGET =
CLIENT.target(ServerMock.CONTEXT
+ BASE_PATH);

public static void main(String[] args) {
consume();
}

private static void consume() {

try (final SseEventSource sseSource =
SseEventSource
.target(WEB_TARGET)
.build()) {

sseSource.register(System.out::println);
sseSource.open();

for (int counter=0; counter < 5; counter++) {
System.out.println(" ");
for (int innerCounter=0; innerCounter < 5;
innerCounter++) {
WEB_TARGET.request().post(Entity.json("event "
+ innerCounter));
}
Thread.sleep(1000);
}

CLIENT.close();
System.out.println("\n All messages consumed");
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
}

To try it out, you have to first run the ServerMock class and then the ClientConsumer class. If everything worked well, you should see something like this:

InboundEvent{name='sse-message', id='1502228257736', comment='',    data=event 0}
InboundEvent{name='sse-message', id='1502228257753', comment='', data=event 1}
InboundEvent{name='sse-message', id='1502228257758', comment='', data=event 2}
InboundEvent{name='sse-message', id='1502228257763', comment='', data=event 3}
InboundEvent{name='sse-message', id='1502228257768', comment='', data=event 4}

These are the messages sent from the server to the client.

How it works...

This recipe is made up of three parts:

  • The server, represented by the ServerMock class
  • The SSE engine, represented by the SseResource class
  • The client, represented by the ClientConsumer class

So once ServerMock is instantiated, it registers the SseResource class:

final ResourceConfig resourceConfig = new ResourceConfig(SseResource.class);
final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(CONTEXT, resourceConfig, false);
server.start();

Then two key methods from SseResource take place. The first one adds messages to the server queue:

addMessage(final String message, @Context Sse sse)

The second one consumes this queue and sends the messages to the clients:

@GET
@Produces(MediaType.SERVER_SENT_EVENTS)
public void getMessageQueue(@Context SseEventSink sink)

Note that this one has a media type SERVER_SENT_EVENTS, introduced in this version for this very purpose. And finally, we have our client. In this recipe, it is both posting and consuming messages.

It consumes here:

sseSource.register(System.out::println);
sseSource.open();

It posts here:

ServerMock.WEB_TARGET.request().post(Entity.json("event " + innerCounter));

See also

Running your first JSF 2.3 code

JavaServer Faces (JSF) is the Java technology made to simplify the process of building a UIs, despite how it's made for the frontend and the UI is built in the backend.

With JSF, you can build components and use (or reuse) them in the UI in an extensible way. You can also use other powerful APIs, such as CDI and Bean Validation, to improve your application and its architecture.

In this recipe, we will use the Validator and Converter interfaces with the new feature introduced by version 2.3, which is the possibility of using them with generic parameters.

Getting ready

First, we need to add the dependencies needed:

        <dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>

How to do it...

  1. Let's create a User class as the main object of our recipe:
public class User implements Serializable {

private String name;
private String email;

public User(String name, String email) {
this.name = name;
this.email = email;
}

//DON'T FORGET THE GETTERS AND SETTERS
//THIS RECIPE WON'T WORK WITHOUT THEM
}
  1. Now, we create a UserBean class to manage our UI:
@Named
@ViewScoped
public class UserBean implements Serializable {

private User user;

public UserBean(){
user = new User("Elder Moraes", "[email protected]");
}

public void userAction(){
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("Name|Password welformed"));
}

//DON'T FORGET THE GETTERS AND SETTERS
//THIS RECIPE WON'T WORK WITHOUT THEM
}
  1. Now, we implement the Converter interface with a User parameter:
@FacesConverter("userConverter")
public class UserConverter implements Converter<User> {

@Override
public String getAsString(FacesContext fc, UIComponent uic,
User user) {
return user.getName() + "|" + user.getEmail();
}

@Override
public User getAsObject(FacesContext fc, UIComponent uic,
String string) {
return new User(string.substring(0, string.indexOf("|")),
string.substring(string.indexOf("|") + 1));
}

}
  1. Now, we implement the Validator interface with a User parameter:
@FacesValidator("userValidator")
public class UserValidator implements Validator<User> {

@Override
public void validate(FacesContext fc, UIComponent uic,
User user)
throws ValidatorException {
if(!user.getEmail().contains("@")){
throw new ValidatorException(new FacesMessage(null,
"Malformed e-mail"));
}
}
}
  1. And then we create our UI using all of them:
<h:body>
<h:form>
<h:panelGrid columns="3">
<h:outputLabel value="Name|E-mail:"
for="userNameEmail"/>
<h:inputText id="userNameEmail"
value="#{userBean.user}"
converter="userConverter" validator="userValidator"/>
<h:message for="userNameEmail"/>
</h:panelGrid>
<h:commandButton value="Validate"
action="#{userBean.userAction()}"/>
</h:form>
</h:body>

Don't forget to run it in a Java EE 8 server.

How it works...

The UserBean class manages the communication between the UI and the server. Once you instantiate the user object, it is available for both of them.

That's why when you run it, the Name | E-mail is already filled (the user object is instantiated when the UserBean class is created by the server).

We associated the userAction() method from the UserBean class to the Validate button of the UI:

<h:commandButton value="Validate" action="#{userBean.userAction()}"/>

You can create other methods in UserBean and do the same to empower your application.

The whole core of our recipe is represented by just a single line in the UI:

<h:inputText id="userNameEmail" value="#{userBean.user}" converter="userConverter" validator="userValidator"/>

So, our two implemented interfaces used here are userConverter and userValidator.

Basically, the UserConverter class (with getAsString and getAsObject methods) converts an object to/from a string and vice versa, according to the logic defined by you.

We have just mentioned it in the preceding code snippet:

value="#{userBean.user}"

The server uses the userConverter object, calls the getAsString method, and prints the result using the preceding expression language.

Finally, the UserValidator class is automatically called when you submit the form, by calling its validate method, and applying the rules defined by you.

There's more...

You could increase the validators by adding a Bean Validation on it and, for example, defining the email property from User with an @Email constraint.

See also

Running your first JSON-P 1.1 code

JSON-Pointer is the Java API for JSON processing. By processing, we mean generating, transforming, parsing, and querying JSON strings and/or objects.

In this recipe, you will learn how to use JSON Pointer to get a specific value from a JSON message in a very easy way.

Getting ready

Let's get our dependency:

<dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
</dependency>

How to do it...

  1. First, we define a JSON message to represent a User object:
{
"user": {
"email": "[email protected]",
"name": "Elder",
"profile": [
{
"id": 1
},
{
"id": 2
},
{
"id": 3
}
]
}
}
  1. Now, we create a method to read it and print the values we want:
public class JPointer {

public static void main(String[] args) throws IOException{
try (InputStream is =
JPointer.class.getClassLoader().getResourceAsStream("user.json");
JsonReader jr = Json.createReader(is)) {

JsonStructure js = jr.read();
JsonPointer jp = Json.createPointer("/user/profile");
JsonValue jv = jp.getValue(js);
System.out.println("profile: " + jv);
}
}
}

The execution of this code prints the following:

profile: [{"id":1},{"id":2},{"id":3}]

How it works...

The JSON Pointer is a standard defined by the Internet Engineering Task Force (IETF) under Request for Comments (RFC) 6901. The standard basically says that a JSON Pointer is a string that identifies a specific value in a JSON document.

Without a JSON Pointer, you would need to parse the whole message and iterate through it until you find the desired value; probably lots of ifs, elses, and things like that.

So, JSON Pointer helps you to decrease the written code dramatically by doing this kind of operation in a very elegant way.

See also

Running your first JSON-B code

JSON-B is an API for converting Java objects to/from JSON messages in a standardized way. It defines a default mapping algorithm to convert Java classes to JSON and still lets you customize your own algorithms.

With JSON-B, Java EE now has a complete set of tools to work with JSON, such as JSON API, and JSON-P. No third-party frameworks are needed anymore (although you are still free to use them).

This quick recipe will show you how to use JSON-B to convert a Java object to and from a JSON message.

Getting ready

Let's add our dependencies to the project:

    <dependencies>
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>yasson</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.1</version>
</dependency>
</dependencies>

How to do it...

  1. Let's create a User class as a model for our JSON message:
public class User {

private String name;
private String email;

public User(){
}

public User(String name, String email) {
this.name = name;
this.email = email;
}

@Override
public String toString() {
return "User{" + "name=" + name + ", email=" + email + '}';
}

//DON'T FORGET THE GETTERS AND SETTERS
//THIS RECIPE WON'T WORK WITHOUT THEM

}
  1. Then, let's create a class to use JSON-B to transform an object:
public class JsonBUser {

public static void main(String[] args) throws Exception {
User user = new User("Elder", "[email protected]");

Jsonb jb = JsonbBuilder.create();
String jsonUser = jb.toJson(user);
User u = jb.fromJson(jsonUser, User.class);

jb.close();
System.out.println("json: " + jsonUser);
System.out.println("user: " + u);

}
}

The result printed is:

json: {"email":"[email protected]","name":"Elder"}
user: User{name=Elder, [email protected]}

The first line is the object transformed into a JSON string. The second is the same string converted into an object.

How it works...

It uses the getters and setters defined in the User class to transform both ways and that's why they are so important.

See also

Running your first Servlet 4.0 code

Servlet 4.0 is one the of biggest APIs of Java EE 8. Since the very beginning of the Java EE platform (the old J2EE), the Servlet specification has always played a key role.

The coolest additions of this version are surely HTTP/2.0 and Server Push. Both of them bring performance improvements to your application.

This recipe will use Server Push to do one of the most basic tasks in a web page—loading an image.

Getting ready

Let's add the dependencies that we need:

<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>

How to do it...

  1. We will create a servlet:
@WebServlet(name = "ServerPush", urlPatterns = {"/ServerPush"})
public class ServerPush extends HttpServlet {

@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse
response) throws ServletException, IOException {

PushBuilder pb = request.newPushBuilder();
if (pb != null) {
pb.path("images/javaee-logo.png")
.addHeader("content-type", "image/png")
.push();
}

try (PrintWriter writer = response.getWriter();) {
StringBuilder html = new StringBuilder();
html.append("<html>");
html.append("<center>");
html.append("<img src='images/javaee-logo.png'><br>");
html.append("<h2>Image pushed by ServerPush</h2>");
html.append("</center>");
html.append("</html>");
writer.write(html.toString());
}
}
}
  1. To try it, run the project in a Java EE 8 server and open this URL:
https://localhost:8080/ch01-servlet/ServerPush

How it works...

We use the PushBuilder object to send an image to the client before it is requested by the img src tag. In other words, the browser doesn't need to do another request (what it usually does with img src) to have an image available for rendering.

It might seem as if it doesn't make too much difference for a single image, but it would with dozens, hundreds, or thousands of images. Less traffic for your client and from your server. Better performance for all!

There's more...

If you are using JSF, you can get the benefits from Server Push for free! You don't even need to rewrite a single line of your code, as JSF relies on the Server Push specification.

Just make sure that you run it under the HTTPS protocol, as HTTP/2.0 only works under it.

See also

Running your first Security API code

Security is one of the top concerns when you build an enterprise application. Luckily, the Java EE platform now has this API that handles many of the enterprise requirements in a standardized way.

In this recipe, you will learn how to define roles and give them the right authorization based on rules defined in the methods that manage sensitive data.

Getting ready

We start by adding our dependencies to the project:

        <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomee</groupId>
<artifactId>openejb-core</artifactId>
<version>7.0.4</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>

How to do it...

  1. We first create a User entity:
@Entity 
public class User implements Serializable{

@Id
private Long id;
private String name;
private String email;

public User(){
}

public User(Long id, String name, String email) {
this.id = id;
this.name = name;
this.email = email;
}

//DON'T FORGET THE GETTERS AND SETTERS
//THIS RECIPE WON'T WORK WITHOUT THEM
}
  1. Here, we create a class to store our security roles:
public class Roles {
public static final String ADMIN = "ADMIN";
public static final String OPERATOR = "OPERATOR";
}
  1. Then, we create a stateful bean to manage our user operations:
@Stateful
public class UserBean {

@PersistenceContext(unitName = "ch01-security-pu",
type = PersistenceContextType.EXTENDED)
private EntityManager em;

@RolesAllowed({Roles.ADMIN, Roles.OPERATOR})
public void add(User user){
em.persist(user);
}

@RolesAllowed({Roles.ADMIN})
public void remove(User user){
em.remove(user);
}

@RolesAllowed({Roles.ADMIN})
public void update(User user){
em.merge(user);
}

@PermitAll
public List<User> get(){
Query q = em.createQuery("SELECT u FROM User as u ");
return q.getResultList();
}
  1. Now, we need to create an executor for each role:
public class RoleExecutor {

public interface Executable {
void execute() throws Exception;
}

@Stateless
@RunAs(Roles.ADMIN)
public static class AdminExecutor {
public void run(Executable executable) throws Exception {
executable.execute();
}
}

@Stateless
@RunAs(Roles.OPERATOR)
public static class OperatorExecutor {
public void run(Executable executable) throws Exception {
executable.execute();
}
}
}
  1. And finally, we create a test class to try our security rules.

Our code uses three test methods: asAdmin(), asOperator(), and asAnonymous().

  1. First, it tests asAdmin():
    //Lot of setup code before this point

@Test
public void asAdmin() throws Exception {
adminExecutor.run(() -> {
userBean.add(new User(1L, "user1", "[email protected]"));
userBean.add(new User(2L, "user2", "[email protected]"));
userBean.add(new User(3L, "user3", "[email protected]"));
userBean.add(new User(4L, "user4", "[email protected]"));

List<User> list = userBean.get();

list.forEach((user) -> {
userBean.remove(user);
});

Assert.assertEquals("userBean.get()", 0,
userBean.get().size());
});
}
  1. Then it tests asOperator():
    @Test
public void asOperator() throws Exception {

operatorExecutor.run(() -> {
userBean.add(new User(1L, "user1", "[email protected]"));
userBean.add(new User(2L, "user2", "[email protected]"));
userBean.add(new User(3L, "user3", "[email protected]"));
userBean.add(new User(4L, "user4", "[email protected]"));

List<User> list = userBean.get();

list.forEach((user) -> {
try {
userBean.remove(user);
Assert.fail("Operator was able to remove user " +
user.getName());
} catch (EJBAccessException e) {
}
});
Assert.assertEquals("userBean.get()", 4,
userBean.get().size());
});
}
  1. And, finally it tests asAnonymous():
    @Test
public void asAnonymous() {

try {
userBean.add(new User(1L, "elder",
"[email protected]"));
Assert.fail("Anonymous user should not add users");
} catch (EJBAccessException e) {
}

try {
userBean.remove(new User(1L, "elder",
"[email protected]"));
Assert.fail("Anonymous user should not remove users");
} catch (EJBAccessException e) {
}

try {
userBean.get();
} catch (EJBAccessException e) {
Assert.fail("Everyone can list users");
}
}
This class is huge! For the full source code, check the link at the end of the recipe.

How it works...

The whole point in this recipe is to do with the @RolesAllowed, @RunsAs, and @PermitAll annotations. They define what operations each role can do and what happens when a user tries an operation using the wrong role.

There's more...

What we did here is called programmatic security; that is, we defined the security rules and roles through our code (the program). There's another approach called declarative security, where you declare the rules and roles through application and server configurations.

One good step up for this recipe is if you evolve the roles management to a source outside the application, such as a database or a service.

See also

Running your first MVC 1.0 code

If you are following the news about Java EE 8, you may now be wondering: why is MVC 1.0 here if it was dropped from the Java EE 8 umbrella?

Yes, it is true. MVC 1.0 doesn't belong (anymore) to the Java EE 8 release. But it didn't reduce the importance of this great API and I'm sure it will change the way some other APIs work in future releases (for example, JSF).

So why not cover it here? You will use it anyway.

This recipe will show you how to use a Controller (the C) to inject a Model (the M) into the View (the V). It also brings some CDI and JAX-RS to the party.

Getting ready

Add the proper dependencies to your project:

        <dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.mvc</groupId>
<artifactId>javax.mvc-api</artifactId>
<version>1.0-pr</version>
</dependency>

How to do it...

  1. Start by creating a root for your JAX-RS endpoints:
@ApplicationPath("webresources")
public class AppConfig extends Application{
}
  1. Create a User class (this will be your MODEL):
public class User {

private String name;
private String email;

public User(String name, String email) {
this.name = name;
this.email = email;
}

//DON'T FORGET THE GETTERS AND SETTERS
//THIS RECIPE WON'T WORK WITHOUT THEM
}
  1. Now, create a Session Bean, which will be injected later in your Controller:
@Stateless
public class UserBean {

public User getUser(){
return new User("Elder", "[email protected]");
}
}
  1. Then, create the Controller:
@Controller
@Path("userController")
public class UserController {

@Inject
Models models;

@Inject
UserBean userBean;

@GET
public String user(){
models.put("user", userBean.getUser());
return "/user.jsp";
}
}
  1. And finally, the web page (the View):
<head>
<meta http-equiv="Content-Type" content="text/html;
charset=UTF-8">
<title>User MVC</title>
</head>
<body>
<h1>${user.name}/${user.email}</h1>
</body>

Run it on a Java EE 8 server and access this URL:

http://localhost:8080/ch01-mvc/webresources/userController

How it works...

The main actor in this whole scenario is the Models class injected into the Controller:

@Inject
Models models;

It's a class from MVC 1.0 API that owns the responsibility, in this recipe, of letting the User object be available for the View layer. It's injected (using CDI) and uses another injected bean, userBean, to do it:

models.put("user", userBean.getUser());

So, the View can easily access the values from the User object using expression language:

<h1>${user.name}/${user.email}</h1>

See also

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Recipes to get you up-and-running with Java EE 8 application development
  • Learn how to apply the major Java EE 8 APIs and specifications
  • Implement microservices and Reactive programming with Java EE 8

Description

Java EE is a collection of technologies and APIs to support Enterprise Application development. The choice of what to use and when can be dauntingly complex for any developer. This book will help you master this. Packed with easy to follow recipes, this is your guide to becoming productive with Java EE 8. You will begin by seeing the latest features of Java EE 8, including major Java EE 8 APIs and specifications such as JSF 2.3, and CDI 2.0, and what they mean for you. You will use the new features of Java EE 8 to implement web-based services for your client applications. You will then learn to process the Model and Streaming APIs using JSON-P and JSON-B and will learn to use the Java Lambdas support offered in JSON-P. There are more recipes to fine-tune your RESTful development, and you will learn about the Reactive enhancements offered by the JAX-RS 2.1 specification. Later on, you will learn about the role of multithreading in your enterprise applications and how to integrate them for transaction handling. This is followed by implementing microservices with Java EE and the advancements made by Java EE for cloud computing. The final set of recipes shows you how take advantage of the latest security features and authenticate your enterprise application. At the end of the book, the Appendix shows you how knowledge sharing can change your career and your life.

Who is this book for?

This book is for developers who want to become proficient with Java EE 8 for their enterprise application development. Basic knowledge of Java is assumed

What you will learn

  • Actionable information on the new features of Java EE 8
  • Using the most important APIs with real and working code
  • Building server side applications, web services, and web applications
  • Deploying and managing your application using the most important Java EE servers
  • Building and deploying microservices using Java EE 8
  • Building Reactive application by joining Java EE APIs and core Java features
  • Moving your application to the cloud using containers
  • Practical ways to improve your projects and career through community involvement

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Apr 09, 2018
Length: 382 pages
Edition : 1st
Language : English
ISBN-13 : 9781788290258
Vendor :
Oracle
Category :
Languages :

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Billing Address

Product Details

Publication date : Apr 09, 2018
Length: 382 pages
Edition : 1st
Language : English
ISBN-13 : 9781788290258
Vendor :
Oracle
Category :
Languages :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total $ 164.97
Architecting Modern Java EE Applications
$54.99
Java EE 8 Cookbook
$54.99
Java EE 8 High Performance
$54.99
Total $ 164.97 Stars icon
Banner background image

Table of Contents

12 Chapters
New Features and Improvements Chevron down icon Chevron up icon
Server-Side Development Chevron down icon Chevron up icon
Building Powerful Services with JSON and RESTful Features Chevron down icon Chevron up icon
Web- and Client-Server Communication Chevron down icon Chevron up icon
Security of Enterprise Architecture Chevron down icon Chevron up icon
Reducing the Coding Effort by Relying on Standards Chevron down icon Chevron up icon
Deploying and Managing Applications on Major Java EE Servers Chevron down icon Chevron up icon
Building Lightweight Solutions Using Microservices Chevron down icon Chevron up icon
Using Multithreading on Enterprise Context Chevron down icon Chevron up icon
Using Event-Driven Programming to Build Reactive Applications Chevron down icon Chevron up icon
Rising to the Cloud – Java EE, Containers, and Cloud Computing Chevron down icon Chevron up icon
Other Books You May Enjoy Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Full star icon Half star icon 4.5
(6 Ratings)
5 star 83.3%
4 star 0%
3 star 0%
2 star 16.7%
1 star 0%
Filter icon Filter
Top Reviews

Filter reviews by




Eyvind Almqvist Mar 17, 2019
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Very practical!
Amazon Verified review Amazon
Bruno Souza Apr 25, 2018
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Having followed Elder during his writing, I'm a bit biased. But even that didn't prepare me for the tour-de-force that this book is!It is a Java EE 8 book, so, it covers all the new features. That's a given. It then goes into the core of JavaEE, with CDI, JPA, EJB, transactions. That's really good and would make a great book. Then the book dives into REST and Communication and then security. Ok, this is amazing! Covering all the JavaEE important features. Ops... But we are not even halfway through the book yet!The "second half" of the book is another book by itself! Standards, Microservices, Reactive apps, containers... Wow. We now go over and above Java EE and see it applied to our daily jobs and challenges.The book is a "cookbook", full of ready to use recipes that you can use immediately to solve real-life problems. It will help you apply Java EE the best way possible: by practicing instead of studying it. I loved and agree with what Ed Burns -- Servlets Spec Lead -- wrote in the foreword: this book should be called a "complete restaurant management with supply chain logistics and a cookbook on top". Well said, Mr. Burns, well said!Do I need to disclaim that I'm cited in the book and that I got a free, signed copy from Elder? I am and I did. But the book is way more amazing then I thought it would be when I saw Elder writing it. You should check it out.PS: BTW, with Jakarta EE just starting, don't miss the appendix, were Elder talks about contributing to the community. That by itself is a career-boosting lesson that can change your life! Just the appendix is worth the book. Just saying...
Amazon Verified review Amazon
Francisco Isidro Massetto Jul 20, 2018
Full star icon Full star icon Full star icon Full star icon Full star icon 5
If you want to learn about emerging technologies, frameworks and APIs on Java EE 8, that's the book!it approaches complex subjects on a very direct and easy to understand way. This book is the best reference for Java developers.
Amazon Verified review Amazon
Andres Galante Apr 25, 2018
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Java EE 8 Cookbook is a fantastic resource for enterprise Java developers. Though easy to follow steps it takes you on a journey to the latest features on Java EE 8.I specially like the chapter about how to write APIs using JSON-P and JSON-b using Lambdas.If you are a Java developer looking for a deep dive into the Java EE 8 world, picking this book is a non brainer.
Amazon Verified review Amazon
Otávio Gonçalves de Santana May 04, 2018
Full star icon Full star icon Full star icon Full star icon Full star icon 5
This book is amazing, it is clean and well structure that makes each chapter independent, so the reader may read each topic as a reference without reading the others. It covers all parts of Java EE 8 and also how to use it with the mainstreams such as cloud computing, event-driven programming, docker and so on.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

How do I buy and download an eBook? Chevron down icon Chevron up icon

Where there is an eBook version of a title available, you can buy it from the book details for that title. Add either the standalone eBook or the eBook and print book bundle to your shopping cart. Your eBook will show in your cart as a product on its own. After completing checkout and payment in the normal way, you will receive your receipt on the screen containing a link to a personalised PDF download file. This link will remain active for 30 days. You can download backup copies of the file by logging in to your account at any time.

If you already have Adobe reader installed, then clicking on the link will download and open the PDF file directly. If you don't, then save the PDF file on your machine and download the Reader to view it.

Please Note: Packt eBooks are non-returnable and non-refundable.

Packt eBook and Licensing When you buy an eBook from Packt Publishing, completing your purchase means you accept the terms of our licence agreement. Please read the full text of the agreement. In it we have tried to balance the need for the ebook to be usable for you the reader with our needs to protect the rights of us as Publishers and of our authors. In summary, the agreement says:

  • You may make copies of your eBook for your own use onto any machine
  • You may not pass copies of the eBook on to anyone else
How can I make a purchase on your website? Chevron down icon Chevron up icon

If you want to purchase a video course, eBook or Bundle (Print+eBook) please follow below steps:

  1. Register on our website using your email address and the password.
  2. Search for the title by name or ISBN using the search option.
  3. Select the title you want to purchase.
  4. Choose the format you wish to purchase the title in; if you order the Print Book, you get a free eBook copy of the same title. 
  5. Proceed with the checkout process (payment to be made using Credit Card, Debit Cart, or PayPal)
Where can I access support around an eBook? Chevron down icon Chevron up icon
  • If you experience a problem with using or installing Adobe Reader, the contact Adobe directly.
  • To view the errata for the book, see www.packtpub.com/support and view the pages for the title you have.
  • To view your account details or to download a new copy of the book go to www.packtpub.com/account
  • To contact us directly if a problem is not resolved, use www.packtpub.com/contact-us
What eBook formats do Packt support? Chevron down icon Chevron up icon

Our eBooks are currently available in a variety of formats such as PDF and ePubs. In the future, this may well change with trends and development in technology, but please note that our PDFs are not Adobe eBook Reader format, which has greater restrictions on security.

You will need to use Adobe Reader v9 or later in order to read Packt's PDF eBooks.

What are the benefits of eBooks? Chevron down icon Chevron up icon
  • You can get the information you need immediately
  • You can easily take them with you on a laptop
  • You can download them an unlimited number of times
  • You can print them out
  • They are copy-paste enabled
  • They are searchable
  • There is no password protection
  • They are lower price than print
  • They save resources and space
What is an eBook? Chevron down icon Chevron up icon

Packt eBooks are a complete electronic version of the print edition, available in PDF and ePub formats. Every piece of content down to the page numbering is the same. Because we save the costs of printing and shipping the book to you, we are able to offer eBooks at a lower cost than print editions.

When you have purchased an eBook, simply login to your account and click on the link in Your Download Area. We recommend you saving the file to your hard drive before opening it.

For optimal viewing of our eBooks, we recommend you download and install the free Adobe Reader version 9.