Building RESTful Web Services with Java EE 8

4.6 (5 reviews total)
By Mario-Leander Reimer
    Advance your knowledge in tech with a Packt subscription

  • Instant online access to over 7,500+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies

About this book

Java Enterprise Edition is one of the leading application programming platforms for enterprise Java development. With Java EE 8 finally released and the first application servers now available, it is time to take a closer look at how to develop modern and lightweight web services with the latest API additions and improvements.

Building RESTful Web Services with Java EE 8 is a comprehensive guide that will show you how to develop state-of-the-art RESTful web services with the latest Java EE 8 APIs. You will begin with an overview of Java EE 8 and the latest API additions and improvements. You will then delve into the details of implementing synchronous RESTful web services and clients with JAX-RS. Next up, you will learn about the specifics of data binding and content marshalling using the JSON-B 1.0 and JSON-P 1.1 APIs.

This book also guides you in leveraging the power of asynchronous APIs on the server and client side, and you will learn to use server-sent events (SSEs) for push communication. The final section covers advanced web service topics such as validation, JWT security, and diagnosability.
By the end of this book, you will have implemented several working web services and have a thorough understanding of the Java EE 8 APIs required for lightweight web service development.

Publication date:
July 2018


Chapter 1. Getting Started with Java EE 8

In this first chapter, you will learn why Java EE is a great platform for building lightweight state-of-the-art microservices. You will learn the latest advances in the different APIs of Java EE 8, with a focus on the more microservice-relevant APIs. You will then learn how to develop, build, run, and package your first microservice powered by Java EE 8.

This chapter includes the following sections:

  • Why is Java EE a good platform for microservices?
  • What's new in Java EE 8?
  • Getting started with Java EE 8 microservices
  • Containerizing Java EE 8 microservices using Docker 

Technical requirements

You need basic programming skills and some Java knowledge. Along with that, you need a computer with a modern operating system, such as Windows 10, macOS, or Linux. We'll be using Maven 3.5 as our build tool and Payara Server as our application server. For the Java 8 application server, you need Docker for Windows, Mac or Linux, an IDE with Java EE 8 support, such as IntelliJ, and a REST client, such as Postman or SoapUI.


Why is Java EE a good platform for microservices?

Well, this is the question, why? And the short answer is simple: because Java EE 8 is the most lightweight enterprise framework currently out there. Let me give you a few more details. First up, Java EE is an industry standard. It's been developed by a vendor-neutral committee and there is widespread knowledge out there because Java EE has been available for a couple of years already. Java EE consists of several specifications, and these specifications have very tight integration. Also, Java EE applies a convention of a configuration programming model, which means that you don't need cumbersome XML descriptors anymore; just throw in a couple of annotations and you're done. For most of the services you're going to develop, you will not need any external dependencies, and this leads to thin deployment artifacts. And finally, you have the availability of modern application servers that suit the cloud era.

Java EE version history

If you have a look at the Java EE version history, which you can find at,_Enterprise_Edition, you'll see we've come a long way since J2EE 1.2 was first released on December 12, 1999. If you look on the far-right side in the following diagram, you can see Java EE 8 was released on September 21, 2017, which means we have 18 years of experience and 18 years of community-built knowledge. Therefore it's definitely a very mature and stable API that's been continually improved:

Java EE version history

Overview of Java EE 8

In the following diagram, you can see an overview of Java EE 8 in its current state, you have loads of APIs here that you can program against, and it should meet most of the needs of any enterprise's web-service development. You've got JPA for persistence, JMS for messaging, good JAX-WS for web services in structure, JAX-RS for REST services, and many more APIs you can use for your modern enterprise's application development:

Overview of Java EE 8

And all you need is the following code, which is the only dependency required; this is the Maven dependency for the Java EE 8 API and leads to no external dependencies. All you need is Java EE 8 and Java 8; this results in very thin artifacts which speeds up your daily development and your deployment cycles, and because you have those thin WAR files, this is very Docker-friendly:


Now there are people out there who say that Java EE 8, especially the application service, should not go in a Docker container, but those heavy times are over; modern application servers are really lightweight, have a look at Payara server or WildFly Swarm, or maybe Open Liberty or Apache TomEE, along with the various other application servers. These servers are very lightweight and are definitely suitable to be run in a Docker container. I hope by now you're convinced that Java EE 8 is indeed the most lightweight enterprise framework currently available. In the next section, we're going to have a look what's new in Java EE 8.


What's new in Java EE 8?

In this section, we're going to take a look at the different APIs of Java EE 8 and the latest advances, with a focus on the more microservice-relevant APIs. We're going to look at JSR 370, which is JAX-RS 2.1; JSR 367, which is the JSON Binding; and also JSR 374, which is the Java API for JSON Processing.

We saw the different APIs in Java EE 8 in the Overview of Java EE 8 section. The ones in blue are the ones that have been added or revamped. We see that CDI is been bumped to version 2.0, mainly focusing on asynchronous events, and the Servlet API has been bumped to version 4.0, adding HTTP2 support. JSF 2.3, which is an API to build server-side UIs, the old JSF bean-managed model, has been removed and it's fully integrated with CDI. On the right-hand side of the figure in the previous section, you see the Bean Validation API, which has been bumped to version 2.0. It's tightly integrated with CDI and has been revamped to fully support Java 8 features such as streams and lambdas. There's also a totally new Security API for cloud security and past security in adding standardized authorization, authentication mechanisms, and APIs. Here, we want to focus on JAX-RS 2.1, JSON-P 1.1, and JSON-B 1.0.

Let's get started with JAX-RS 2.1. First, it improved the integration with CDI, so all your resource beans are properly CDI-managed. It's also been tightly integrated with JSON-B for JSON marshalling and JSON-P for JSON Processing. Also, server-sent events have been added to implement push notifications. They support non-blocking I/O and all the providers, such as filters and interceptors for JAX-RS. There's also been an improved JAX-RS, which is a synchronous client API supporting a completion stage. If you have a look at the Java API for JSON Processing, it's been updated to version 1.1 to support JSON Pointer and JSON Patch. It allows you to edit and transform operations for your JSON object model, and the API has been updated to work with Java SE 8 features, such as lambdas and streams.

The new kid on the block is JSON-B, the JSON Binding 1.0 API. It's the new standard way to convert JSON into Java objects and vice-versa. For a long time, we've had JSON-B to do the same for XML, and JSON-B is the API to do that for JSON. JSON-B leverages JSON-P and provides a conversion layer above it. It provides a default mapping algorithm for converting existing Java classes to JSON. The mapping is highly customizable through the use of Java annotations, and you can plug in different JSON-B runtimes to convert Java objects to and from JSON, such as Jackson. Those are the most relevant Java EE 8 APIs with respect to web-service development. In the next section, we're getting started with Java EE 8 microservices development.


Getting started with Java EE 8 microservices

In this section, we're going to take a look at the following things:

  • How to develop, build, and run your first Java-EE-8-powered microservice
  • Required Java EE 8 dependencies for basic web-service development
  • Basic components of any JAX-RS-based web service
  • Deployment of a thin WAR artifact using Payara Server 5

Let's get started and dive into the code. I've prepared my IDE and a raw skeleton Maven project. What you see here is a very basic POM file:

There's one thing missing though; first, we need to define the required dependency for the Java EE 8 API. Let's do that:


We specify version as 8.0. We should also define the proper scope for this, which is provided in this case because the Java EE 8 API will later be provided by our application server and we are done with our dependency. Next, we should add a beans.xml descriptor to the WEB-INF directory of our web application:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=""

We do this and we're done, what's next? Well, next we should bootstrap our JAX-RS application. Now let's create a class called JAXRSConfiguration. The name really doesn't matter. What's important is that this class extends from the Application base class. Bear in mind the package while selecting theApplication. It's also important that you specify the @ApplicationPath annotation. This will be the base path our REST API will be accessible under, thus we call that "api":

package com.packtpub.javaee8;


 * Configures a JAX-RS endpoint.
public class JAXRSConfiguration extends Application {

Once we've bootstrapped JAX-RS, what's missing is a proper REST resource. Let's create a class called HelloWorldResouce. We used the @Path annotation, which will be the path this resource will be accessible under. We'll call that "hello". Next up, we create a method that will produce the proper response once called, we call that helloWorld. We use the proper Response here. We annotate this using the @GET annotation because we will be issuing GET requests later on, and we'll say that it produces MediaType.APPLICATION_JSON. Then we return Response.ok, where ok is HTTP status 200 of a response when we call the build. So, what should be used as the response? We'll be using Map<String, String> as our response and will return singletonMap with the message key and the Hello World value:

package com.packtpub.javaee8;

import java.util.Map;

import static java.util.Collections.singletonMap;

 * The REST resource implementation class.
public class HelloWorldResource {
    public Response helloWorld() {
        Map<String, String> response = singletonMap("message", 
          "Building Web Services with Java EE 8.");
        return Response.ok(response).build();

We should already have a very simple working microservice. Now let's deploy this onto our Payara Server 5 and run it. We're going to deploy the WAR file, it's been built; you can see that it's already been deployed and the deployment took 5.1 milliseconds.

Let's check our browser. You should see the "Hello World." message, as shown in the following screenshot:

If you don't trust me, let's just modify the value here to "Building Web Services with Java EE 8." value. We deploy this once more and update our artifact. The new version has been deployed. Let's go back to our browser to check that we have the proper response message, as shown in the following screenshot:

That's all for this section; in the next section, I'm going to show you how to containerize your Java EE 8 microservice.


Containerizing Java EE 8 microservices

In this section, we're going to take a look at how to containerize and run our Java EE 8 microservice using Docker. We'll learn how to write a basic Docker file, and we'll also see how to build and run the Docker image using Payara Server full and Payara Server micro edition. Let's open our IDE again to the microservice project from the previous section; all that's missing here is Dockerfile, therefore let's create one.

Now the question is: what base image should we use? We have two basic options when using Payara: you can either use the server-full image or the Payara micro edition. Let's use the full version of Payara first. Dockerfile will be as follows:

FROM payara/server-full:5-SNAPSHOT

COPY target/hello-javaee8.war $DEPLOY_DIR

In the preceding Dockerfile, we mentioned that we're using payara/server-full. We need to use the correct version of it, in our case this is version 5-SNAPSHOT, and then copy the hello-javaee8.war file of our microservice into the correct location of the produced image. We need to issue a COPY command from target/hello-javaee8.war and then copy this into the deployment directory, that should be it, let's see whether is worked. We open a console, making sure that we're in the right directory. We check that everything is packaged nicely, and to do this we call mvn package just to make sure the WAR file is in the correct state. If it is, you'll see my things running while compiling, an absence of tests, and the WAR file is up to date:

We build Docker using -t, which specifies the tag we want to use, we do that by calling hello-javaee8 and we give it a version number, 1.0:

>docker build -t hello-javaee8:1.0 .

Using the following command, let's see whether our server starts up:

>docker run -it -p 8080:8080 hello-javaee8:1.0

We mapped port 8080 from the container onto our Docker host. You'll see that the Payara GlassFish Server is starting up in the console—it should only take a couple of seconds—and in a second we should see that our application is deployed. To check that we can reach our web service hit the IP address as shown in the following screenshot. This is the IP address of my Docker host port 8080 and we can access our service, which was successful:

Now let's stop that and delete the contents of this Dockerfile. I want to show you how to use the Payara micro edition instead. First, we need to change FROM. To do this we use a different base tag for this image (payara/micro:5-SNAPSHOT), and then copy the hello-javaee8.war file into the proper location for this base image. Next we copy our WAR file in the target directory and we call it to our /opt/payara/deployments. This is the default deployments directory for the micro edition base container. The Dockerfile should look as follows:

FROM payara/micro:5-SNAPSHOT

COPY target/hello-javaee8.war /opt/payara/deployments

Switch back to the console and issue the Docker build command again:

>docker build -t hello-javaee8:1.0 .

Fire up the container again:

>docker run -it -p 8080:8080 hello-javaee8:1.0



You can see that the output in the console changes and we're using the Payara micro runtime this time. This takes a couple of seconds to spin up our web service, and in a few seconds it should be done. We can see that our REST Endpoints are available. Let's check again. We go to our management console and we can see that we have a running container. Try calling the web service from the browser, as shown in the following screenshot:

We can see that everything's working fine and we have a running Dockerized version of our web service.



In this chapter, we talked about Java EE and the fact that it's a great platform for building modern and lightweight web services. We had a look at the different APIs of Java EE 8 and the latest advances, with a focus on the more microservice-relevant APIs, such as JAX-RS, JSON-B, and JSON-P. We then developed, built, and ran our Java-EE-8-powered microservice and deployed it locally to the Payara Server. In the final section, we containerized and ran our Java EE 8 microservice using Docker.

In the next chapter, we'll do a deep dive into building synchronous web services and clients using the relevant JAX-RS APIs.

About the Author

  • Mario-Leander Reimer

    Mario-Leander Reimer is a chief technologist for QAware GmbH. He is a senior Java developer and architect with several years' experience in designing complex and large-scale distributed system architectures. He is continuously looking for innovations and ways to combine and apply state-of-the-art technology and open-source software components in real-world customer projects. He studied computer science at Rosenheim and Staffordshire University and he also teaches cloud computing as a part-time lecturer.

    Browse publications by this author

Latest Reviews

(5 reviews total)
Great book with many interesting tips
See the following comment
It is good. it is useful. it is particle. I shall use it in my work

Recommended For You

Book Title
Unlock this book and the full library for only $5/m
Access now