Note
|
This repository contains the guide documentation source. To view the guide in published form, view it on the Open Liberty website. |
Explore how to access a simple RESTful web service and consume its resources in Java using JSON-B and JSON-P.
artists.json
link:finish/src/resources/artists.json[role=include]
You will learn how to access a REST service, serialize a Java object that contains a list of artists and their albums, and use two different approaches to deserialize the returned JSON resources. The first approach consists of using the Java API for JSON Binding (JSON-B) to directly convert JSON messages into Java objects. The second approach consists of using the Java API for JSON Processing (JSON-P) to process the JSON.
The REST service that provides the artists and albums resources has already been written for you and is accessible at the following link when the server is running http://localhost:9080/artists
Which responds with the artists.json
You will implement the following two endpoints using the two deserialization approaches:
-
…/artists/total
to return the total number of artists in the JSON -
…/artists/total/<artist>
to return the total number of albums in the JSON for the particular artist
If you are interested in learning more about REST services and how you can write them, read Creating a RESTful web service.
This guide is already setup with a general application. As you progress through the guide you will make updates to the code directly, and then push updates to the server so you can see the results.
To start the REST service, run the Maven install
and liberty:start-server
goals from
the start
directory:
mvn install liberty:start-server
When the server is running, you can find your service at http://localhost:9080/artists
Artist.java
link:finish/src/main/java/io/openliberty/guides/consumingrest/model/Artist.java[role=include]
Album.java
link:finish/src/main/java/io/openliberty/guides/consumingrest/model/Album.java[role=include]
To deserialize a JSON message, start with creating Plain Old Java Objects (POJOs) that represent what is in the JSON and whose instance members map to the keys in the JSON.
For the purpose of this guide, you are given two POJOs.
The Artist
object has two instance members name
and albums
,
which map to the artist name and the collection of the albums they have written. The Album
object represents a
single object within the album collection, and contains three instance members title
, artistName
, and totalTracks
, which map to the album title, the artist who wrote the album, and the number of tracks the album contains.
JSON-B is a feature introduced with Java EE 8 and strengthens Java support for JSON. With JSON-B you directly serialize and deserialize POJOs. This API gives you a variety of options for working with JSON resources.
In contrast, you need to use helper methods with JSON-P to process a JSON response. This tactic is more straightforward, but it can be cumbersome with more complex classes.
JSON-B is built on top of the existing JSON-P API. JSON-B can do everything that JSON-P can do and allows for more customization for serializing and deserializing.
Artist.java
link:finish/src/main/java/io/openliberty/guides/consumingrest/model/Artist.java[role=include]
JSON-B requires a POJO to have a public default no-argument constructor for deserialization and binding to work properly.
The JSON-B engine includes a set of default mapping rules, which can be run without any customization annotations or custom configuration. In some instances, you might find it useful to deserialize a JSON message with only certain fields, specific field names, or classes with custom constructors. In these cases, annotations are necessary and recommended:
-
The
@JsonbProperty
annotation to map JSON keys to class instance members and vice versa. Without the use of this annotation, JSON-B will attempt to do POJO mapping, matching the keys in the JSON to the class instance members by name. JSON-B will attempt to match the JSON key with a Java field or method annotated with@JsonbProperty
where the value in the annotation exactly matches the JSON key. If no annotation exists with the given JSON key, JSON-B will attempt to find a matching field with the same name. If a match cannot be found, JSON-B will attempt to find a matching getter (for serialization) or setter (for de-serialization) method whose property name matches the JSON key. If no matching getter/setter method can be found, then serialization/de-serialization will fail with an exception. The Artist POJO does not require this annotation because all instance members match the JSON keys by name. -
The
@JsonbCreator
and@JsonbProperty
annotations to annotate a custom constructor. These annotations are required for proper parameter substitution when a custom constructor is used. -
The
@JsonbTransient
annotation to define an object property that does not map to a JSON property. While the use of this annotation is good practice, it is only necessary for serialization.
For more information on customization with JSON-B, see the official JSON-B site.
Artist.java
link:finish/src/main/java/io/openliberty/guides/consumingrest/model/Artist.java[role=include]
Album.java
link:finish/src/main/java/io/openliberty/guides/consumingrest/model/Album.java[role=include]
Consumer.java
link:finish/src/main/java/io/openliberty/guides/consumingrest/Consumer.java[role=include]
The Artist
and Album
POJOs are ready for deserialization.
Next, we’ll learn to consume the JSON response from your REST service.
Create theConsumer
class.src/main/java/io/openliberty/guides/consumingrest/Consumer.java
Consumer.java
link:finish/src/main/java/io/openliberty/guides/consumingrest/Consumer.java[role=include]
pom.xml
link:finish/pom.xml[role=include]
JSON-B is a Java API that is used to serialize Java objects to JSON messages and vice versa.
Open Liberty’s JSON-B feature on Maven Central includes the JSON-B provider through transitive dependencies.
The JSON-B provider
has been added as a dependency in your pom.xml
The consumeWithJsonb()
method in the Consumer
class makes a GET
request to the
running artist service and retrieves the JSON. Then binds the JSON into an Artist
array, use the Artist[]
entity type in the readEntity
call.
Consumer.java
link:finish/src/main/java/io/openliberty/guides/consumingrest/Consumer.java[role=include]
The consumeWithJsonp()
method in the Consumer
class makes a GET
request
to the running artist service and retrieves the JSON. This method then uses the
collectArtists
and collectAlbums
helper methods. These helper methods will
parse the JSON and collect its objects into individual POJOs. Notice that you can
use the custom constructors to create instances of Artist
and Album
.
Consumer.java
link:finish/src/main/java/io/openliberty/guides/consumingrest/Consumer.java[role=include]
ArtistResource.java
link:finish/src/main/java/io/openliberty/guides/consumingrest/service/ArtistResource.java[role=include]
Now that you can consume a JSON resource you can put that data to use.
Replace theArtistResource
class.src/main/java/io/openliberty/guides/consumingrest/service/ArtistResource.java
-
The
getArtists()
method provides the raw JSON data service that you accessed at the beginning of this guide. -
The
getJsonString()
method uses JSON-B to return the JSON as a string that will be used later for testing. -
The
getTotalAlbums()
method uses JSON-B to return the total number of albums present in the JSON for a particular artist. The method returns -1 if this artist does not exist. -
The
getTotalArtists()
method uses JSON-P to return the total number of artists present in the JSON.
The methods that you wrote in the Consumer
class could be written directly in the
ArtistResource
class. However, if you are consuming a REST resource from a third
party service, you should separate your GET
/POST
requests from your data consumption.
When the server is running, you can find your service at http://localhost:9080/artists
ConsumingRestTest.java
link:finish/src/test/java/it/io/openliberty/guides/consumingrest/ConsumingRestTest.java[role=include]
Create theConsumingRestTest
class.src/test/java/it/io/openliberty/guides/consumingrest/ConsumingRestTest.java
Maven finds and executes all tests under it/
and each test method must be marked with the @Test
annotation.
You can use the @BeforeClass
and @AfterClass
annotations to perform any one time setup and teardown
tasks before and after all of your tests execute, as well as the @Before
and @After
annotations
to do the same but for each individual test case.
ConsumingRestTest.java
link:finish/src/test/java/it/io/openliberty/guides/consumingrest/ConsumingRestTest.java[role=include]
pom.xml
link:finish/pom.xml[role=include]
For your test classes to have access to JSON-B, the yasson
dependency has been added in your pom.xml
.
The testArtistDeserialization
test case checks that Artist
instances created from
the REST data and those that are hardcoded perform the same.
The assertResponse
helper method ensures that the response code you receive is valid (200).
ConsumingRestTest.java
link:finish/src/test/java/it/io/openliberty/guides/consumingrest/ConsumingRestTest.java[role=include]
The testJsonBAlbumCount
and testJsonBAlbumCountForUnknownArtist
tests both use the total/{artist}
endpoint which invokes JSON-B.
The testJsonBAlbumCount
test case checks that deserialization with JSON-B was done correctly
and that the correct number of albums is returned for each artist in the JSON.
The testJsonBAlbumCountForUnknownArtist
test case is similar to testJsonBAlbumCount
but instead checks an artist that does not exist in the JSON and ensures that a
value of '-1' is returned.
ConsumingRestTest.java
link:finish/src/test/java/it/io/openliberty/guides/consumingrest/ConsumingRestTest.java[role=include]
The testJsonPArtistCount
test uses the total
endpoint which invokes JSON-P. This test
checks that deserialization with JSON-P was done correctly and that the correct number
of artists is returned.
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running it.io.openliberty.guides.consumingrest.ConsumingRestTest
Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.59 sec - in it.io.openliberty.guides.consumingrest.ConsumingRestTest
Results :
Tests run: 4, Failures: 0, Errors: 0, Skipped: 0
You have just accessed a simple RESTful web service and consumed its resources using JSON-B and JSON-P in Open Liberty.