The JSON format is commonly used in RESTful web services to exchange messages. In this section, we will discuss how the Java API or JSON processing is used in a RESTful web service. First, add the RESTful web service dependency to pom.xml
:
<dependency> <groupId>javax.ws.rs</groupId> <artifactId>javax.ws.rs-api</artifactId> <version>2.0</version> </dependency>
Create a sample REST web service to test the JSON API. Create a resource class JsonResource
annotated with @PATH
to identify the URI path. Here's how we accomplish this:
package org.json; import java.io.StringReader; import javax.ws.rs.GET; import javax.ws.rs.Produces; import javax.ws.rs.Path; import javax.json.*; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; @Path("jaxrs") public class JsonResource { }
To package the resource class, create a class that extends the javax.ws.rs.core.Application
class. Annotate the Application
subclass with the @ApplicationPath
annotation to define the base URI pattern for the resource. Override the getClasses()
method to return the list of RESTful web service resources. Add the org.json.JsonResource
class to HashSet
to return from the getClasses()
method. The JsonResourceApplication
class extends Application
subclass, as listed here:
package org.json; import java.util.HashSet; import java.util.Set; import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; @ApplicationPath("resources") public class JsonResourceApplication extends Application { @Override public Set<Class<?>> getClasses() { Set<Class<?>> set = new HashSet<Class<?>>(); set.add(org.json.JsonResource.class); return set; } }
Java EE 7 provides support for the JsonObject
/JsonArray
/JsonStructure
API in a RESTful web service. JsonObject
/JsonArray
/JsonStructure
can be used as return type and parameter type in a resource method. In this section, we use JsonArray
as the return type of a resource method. Add a resource method (getJsonMessage()
) in the JsonResource
class that produces application/json
and accepts GET
requests. In the resource method, create JsonReader
from StringReader
, and create JsonArray
from JsonReader
, which was also discussed in the previous section. Return JsonArray
from the resource method listed here:
@GET @Produces({MediaType.APPLICATION_JSON}) public JsonArray getJsonMessage() { JsonReader jsonReader = Json.createReader(new StringReader("[{"title":"PaaS Fits the Enterprise","author":"David Baum"},{"title":"On Becoming Others, Limits, and Restoration","author":"Tom Kyte"}]")); JsonArray array = jsonReader.readArray(); jsonReader.close(); return array; }
Create the jaxrsGetJsonReturnType.jsp
JSP. In this JSP, use the new Client
API introduced in JAX-RS 2.0 to create Client
and invoke the RESTful web service. Create a Client
object from the ClientBuilder
static method newClient()
. A Client
object is used to send requests and receive responses from a RESTful web service. In the fluent Client
API method, invocations can be linked. Invoke the target(String)
method to build a new web resource target.
Build the resource path using the path()
method. Add "resources"
to the path for the Application
subclass. Add "jaxrs"
to the path to access the resource class JsonResource
. As the getJsonMessage()
method is not annotated with @PATH
, we won't add a path component for the resource method. Build the request with the request()
method, and specify the acceptable response type as application/json
(or MediaType.APPLICATION_JSON
). Invoke the get()
method for the request and specify the Java type of the response entity as JsonArray.class
:
Client client = ClientBuilder.newClient(); JsonArray array = client.target("http://localhost:8080/json-1.0").path("resources").path("jaxrs").request(MediaType.APPLICATION_JSON).get(JsonArray.class);
Obtain JsonObject
in JsonArray
, which is returned from the REST web service using the getJsonObject(int index)
method. For example, the name/value pairs in the first JsonObject
in JsonArray
are output as follows:
JsonObject catalog = array.getJsonObject(0); out.println("Title: "+catalog.getString("title")); out.println("Author: "+catalog.getString("author"));
The jaxrsGetJsonReturnType.jsp
file is listed here:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ page import="javax.ws.rs.client.ClientBuilder,javax.ws.rs.client.Client ,javax.json.*,javax.json.stream.*,javax.ws.rs.core.*"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>JSON Array</title> </head> <body> <% Client client = ClientBuilder.newClient(); JsonArray array = client.target("http://localhost:8080/json"). path("resources").path ("jaxrs").request(MediaType.APPLICATION_JSON). get(JsonArray.class); JsonObject catalog = array.getJsonObject(0); out.println("Title: "+catalog.getString("title")); out.println("<br/>"); out.println("Author: "+catalog.getString("author")); out.println("<br/>"); JsonObject catalog2 = array.getJsonObject(1); out.println("Title: "+catalog2.getString("title")); out.println("<br/>"); out.println("Author: "+catalog2.getString("author")); out.println("<br/>"); %> </body> </html>
The directory structure of the json
application is shown here:
Before deploying the application, run Maven clean to delete the deployment classes from the previous Maven build. Remove the json.war
file from the deployments
directory of the WildFly server. Run Maven install as explained earlier to deploy the JSON application to WildFly. Start WildFly if it is not already started. Run jaxrsGetJsonReturnType.jsp
with the http://localhost:8080/json/jaxrsGetJsonReturnType.jsp
URL in a browser to invoke the RESTful web service, and output the name/value pairs in JsonArray
, which is returned from the web service, as shown here:
JsonObject
/JsonArray
can be used as a resource method parameter type, but it has a limitation; a JsonObject
/JsonArray
type cannot not be included in a GET
request because the GET
request URI must not contain special characters (such as {
,}
, [
, and ]
) that are used in JSON. A JSON object or array must be UTF-8 encoded to String
for the request URI and, therefore, the parameter type of a resource method cannot be JsonObject
/JsonArray
without using a provider to convert from string to JsonObject
/JsonArray
(an approach we discuss in a later section). In this section, we encode JsonObject
as String
and send a request to a resource method with a @QueryParam
annotated parameter of the type String
.
In the resource class JsonResource
, add a resource method that has an annotated parameter, @QueryParam
, of the type String
. In the resource method, create JsonObject
from String
by first creating JsonReader
using StringReader
and subsequently obtaining JsonObject
with the readObject()
method. Obtain the "catalog"
JSON array from JsonObject
using the getJsonArray()
method and return the JsonArray
object. Add the following resource method to the JsonResource
class:
@Path("jsonp") @GET @Produces({MediaType.APPLICATION_JSON}) public JsonArray getJsonArray(@QueryParam("jsonObject") String jsonObjectStr) { JsonReader jsonReader = Json.createReader(new StringReader(jsonObjectStr)); JsonObject jsonObject = jsonReader.readObject(); jsonReader.close(); JsonArray jsonArray = jsonObject.getJsonArray("catalog"); return jsonArray; }
Add the jaxrsGetJsonStringMethodParam.jsp
JSP. In this JSP, build a JsonObject
object, as discussed in an earlier section Creating JSON. Encode JsonObject
to a UTF-8 String
using the URLEncoder.encode(String,String)
static method, as follows:
String jsonObjectStr = URLEncoder.encode(jsonObject.toString(), "UTF-8");
Build the client request using the fluent Client
API. Create a Client
object from ClientBuilder
using the static method newClient()
. Build the web resource target using http://localhost:8080/json
as the base URI. Add URI paths for the Application
subclass (path ("resources")
), resource class (path ("jaxrs")
), and resource method (path ("jsonp")
). Set the jsonObject
query parameter value to the encoded jsonObjectStr
string using the queryParam()
method. Build the request using the request method and invoke the request to get a response of the JsonArray.class
Java type using the get
method:
Client client = ClientBuilder.newClient(); JsonArray array = client.target("http://localhost:8080/json").path("resources").path ("jaxrs").path("jsonp").queryParam("jsonObject",jsonObjectStr).req uest(MediaType.APPLICATION_JSON).get(JsonArray.class);
Output the name/value pairs in the JSON array, as discussed in the previous section. The jaxrsGetJsonStringMethodParam.jsp
is listed here:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ page import="java.net.URLEncoder,java.io.StringReader, javax.ws.rs.client.ClientBuilder, javax.ws.rs.client.Client,javax.json.*, javax.json.stream.*,javax.ws.rs.core.*"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>JSON Array</title> </head> <body> <% JsonObjectBuilder builder = Json.createObjectBuilder(); builder = builder.add("journal", "Oracle Magazine"); builder = builder.add("edition", Json.createObjectBuilder().add("date", "March April 2013") .add("cover", "Public Cloud. Private Cloud")); builder = builder .add("catalog", Json.createArrayBuilder() .add(Json .createObjectBuilder() .add("title", "PaaS Fits the Enterprise") .add("author", "David Baum")) .add(Json .createObjectBuilder() .add("title", "On Becoming Others, Limits, and Restoration") .add("author", "Tom Kyte"))); JsonObject jsonObject = builder.build(); String jsonObjectStr = URLEncoder.encode(jsonObject.toString(), "UTF-8"); Client client = ClientBuilder.newClient(); JsonArray array = client.target("http://localhost:8080/json") .path("resources").path("jaxrs").path("jsonp") .queryParam("jsonObject", jsonObjectStr) .request(MediaType.APPLICATION_JSON).get(JsonArray.class); JsonObject catalog = array.getJsonObject(0); out.println("Title: " + catalog.getString("title")); out.println("<br/>"); out.println("Author: " + catalog.getString("author")); out.println("<br/>"); JsonObject catalog2 = array.getJsonObject(1); out.println("Title: " + catalog2.getString("title")); out.println("<br/>"); out.println("Author: " + catalog2.getString("author")); out.println("<br/>"); %> </body> </html>
Run jaxrsGetJsonStringMethodParam.jsp
with the URL http://localhost:8080/json/jaxrsGetJsonStringMethodParam.jsp
in a browser to output JSON array name/value pairs, as shown in the next screenshot. Because of the UTF-8 encoding of JsonObject
to String
, the whitespace is replaced with a +
in the String
values output:
We couldn't send the JSON object in a GET
request without encoding it into String
, because a GET
request includes the key/value pairs in the request URI. A JSON object in the request URI would generate an org.apache.jasper.JasperException: javax.ws.rs.core.UriBuilderException: java.net.URISyntaxException
exception.
A JSON object can be sent in a POST
request as the key/value pairs are sent in the request itself and not the request URI. In this section, we will send a POST
request to a resource method that has a JsonObject
type parameter. In the resource method, obtain the "catalog"
JsonArray from JsonObject
and return the JsonArray
object. Add a resource method annotated with @POST
and with a JsonObject
parameter, as follows:
@Path("post") @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public JsonArray post(final JsonObject jsonObject) { JsonArray jsonArray = jsonObject.getJsonArray("catalog"); return jsonArray; }
Create the jaxrsPostJsonMethodParam.jsp
JSP, which creates a JsonObject
object as in the previous subsections on Processing JSON in a RESTful web service. Create a Client
object using the fluent Client
API. Build the web resource path by including the path URI for the post resource method. Build a POST
request invocation using the buildPost(Entity<?> entity)
method. Create an Entity<JsonObject>
object using the static method json(T entity)
in javax.ws.rs.client.Entity<T>
. Invoke the request using the invoke(Class<T> responseType)
method with the response type JsonArray.class
:
JsonObject jsonObject = builder.build(); Client client = ClientBuilder.newClient(); JsonArray array = client.target("http://localhost:8080/json"). path("resources").path("jaxrs").path("post"). request(MediaType.APPLICATION_JSON). buildPost(Entity.json(jsonObject)).invoke(JsonArray.class);
Output the name/value pairs in the JSON array. The jaxrsPostJsonMethodParam.jsp
file is listed here:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ page import="javax.ws.rs.client.*,java.io.StringReader, javax.json.*,javax.json.stream.*, javax.ws.rs.core.*"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>JSON Array</title> </head> <body> <% JsonObjectBuilder builder = Json.createObjectBuilder(); builder=builder.add("journal", "Oracle Magazine"); builder=builder.add("edition", Json.createObjectBuilder().add("date","March April 2013").add("cover", "Public Cloud. Private Cloud")); builder=builder.add("catalog", Json.createArrayBuilder(). add(Json.createObjectBuilder(). add("title","PaaS Fits the Enterprise").add("author","David Baum")).add(Json.createObjectBuilder(). add("title","On Becoming Others, Limits, and Restoration").add("author","Tom Kyte"))); JsonObject jsonObject = builder.build(); Client client = ClientBuilder.newClient(); JsonArray array = client.target("http://localhost:8080/json").path("resources").path ("jaxrs").path("post").request(MediaType.APPLICATION_JSON).buildPo st(Entity.json(jsonObject)).invoke(JsonArray.class); JsonObject catalog=array.getJsonObject(0); out.println("Title: "+catalog.getString("title")); out.println("<br/>"); out.println("Author: "+catalog.getString("author")); out.println("<br/>"); JsonObject catalog2 = array.getJsonObject(1); out.println("Title: "+catalog2.getString("title")); out.println("<br/>"); out.println("Author: "+catalog2.getString("author")); out.println("<br/>"); %> </body> </html>
The directory structure of the json
application is shown in Package Explorer in the following screenshot:
Run Maven clean to delete previously generated deployment files, and run Maven install to redeploy the json
application. Then, run jaxrsPostJsonMethodParam.jsp
in the http://localhost:8080/json/jaxrsPostJsonMethodParam.jsp
URL to output name/value pairs in the JSON array, as shown in next screenshot. As we did not encode the JSON object sent with the request, the JSON array
string values have whitespace instead of +
.