Convert List, Map to JSON in REST Response using Jersey

Introduction

In this post we will see how to convert List, Map to JSON in REST Response using Jersey API. We will create three separate REST methods to convert List to JSOn, Map to JSON and List of Map to JSON string. We will annotate the REST resource class with @Path for having the base URI of the REST resources. We will use @Produces annotations to indicate what type of data the REST resource methods will produce in the response. We also use @GET annotation for http GET verb.

The most important concept in REST is resources, which are identified by global IDs — typically using URIs. Client applications use HTTP methods (GET/ POST/ PUT/ DELETE) to manipulate the resource or collection of resources. A RESTful Web service is implemented using HTTP and the principles of REST.

Typically, a RESTful Web service should define the following aspects:

  • The base/root URI for the Web service such as http://<host>/<appcontext/contextpath>/<url pattern>/<resources>.
  • The MIME type of the response data supported, which are JSON/XML/TEXT/HTML etc.
  • The set of operations supported by the service. (for example, POST, GET, PUT or DELETE).

HTTP Methods

HTTP methods are mapped to CRUD (create, read, update and delete) actions for a resource. Although you can make slight modifications such as making the PUT method to create or update, the basic patterns are listed as follows.

HTTP GET: Get/List/Retrieve an individual resource or a collection of resources.
HTTP POST: Create a new resource or resources.
HTTP PUT: Update an existing resource or collection of resources.
HTTP DELETE: Delete a resource or collection of resources.

Prerequisites

Eclipse Neon, JDK 1.8, Maven 3.6.0, Jersey 2.6

Example with Source Code

Creating Project

Create maven project in Eclipse with the below information:

Group Id: com.roytuts
Artifact Id: jersey-rest-map-list-to-json

The maven project in Eclipse looks similar to the following image:

convert list map to json in rest using jersey

Updating Build File – pom.xml

Update the default generated pom.xml file to include the required dependencies for downloading the jars for the project.

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.roytuts</groupId>
	<artifactId>jersey-rest-map-list-to-json</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<url>http://maven.apache.org</url>
	<properties>
		<jersey.version>2.6</jersey.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>javax.ws.rs</groupId>
			<artifactId>javax.ws.rs-api</artifactId>
			<version>2.0</version>
		</dependency>
		<dependency>
			<groupId>org.glassfish.jersey.core</groupId>
			<artifactId>jersey-server</artifactId>
			<version>2.6</version>
		</dependency>
		<dependency>
			<groupId>org.glassfish.grizzly</groupId>
			<artifactId>grizzly-http-server</artifactId>
			<version>2.3.11</version>
		</dependency>
		<dependency>
			<groupId>org.glassfish.jersey.containers</groupId>
			<artifactId>jersey-container-servlet</artifactId>
			<version>${jersey.version}</version>
		</dependency>
		<dependency>
			<groupId>org.glassfish.jersey.bundles.repackaged</groupId>
			<artifactId>jersey-guava</artifactId>
			<version>${jersey.version}</version>
		</dependency>
		<dependency>
			<groupId>org.glassfish.jersey.containers</groupId>
			<artifactId>jersey-container-grizzly2-http</artifactId>
			<version>${jersey.version}</version>
		</dependency>
		<dependency>
			<groupId>org.glassfish.jersey.test-framework.providers</groupId>
			<artifactId>jersey-test-framework-provider-inmemory</artifactId>
			<version>${jersey.version}</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.0.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>com.google.code.gson</groupId>
			<artifactId>gson</artifactId>
			<version>2.2.4</version>
		</dependency>
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.1.1</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
	<build>
		<finalName>jersey-rest-map-list-to-json</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.6.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Updating Deployment Descriptor – web.xml

Modify web.xml file to use the jersey servlet and let the container where are our REST resource classes.

<web-app 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/web-app_3_1.xsd"
	version="3.1">
	<display-name>Asynchronous REST- Connection Callback</display-name>
	<servlet>
		<servlet-name>REST</servlet-name>
		<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
		<init-param>
			<param-name>jersey.config.server.provider.packages</param-name>
			<param-value>com.roytuts.rest.resources</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<!-- Map /rest/* to Jersey -->
	<servlet-mapping>
		<servlet-name>REST</servlet-name>
		<url-pattern>/*</url-pattern>
	</servlet-mapping>
</web-app>

Creating DTO Class

We need DTO or VO class to convert object into JSON. This class defines a book with few common attributes, such as, book unique id, title, author, isbn.

package com.roytuts.rest.dto;
public class Book {
	private Long id;
	private String title;
	private String author;
	private String isbn;
	public Book(Long id, String title, String author, String isbn) {
		this.id = id;
		this.title = title;
		this.author = author;
		this.isbn = isbn;
	}
	//getters and setters
}

Creating Repository

We are not going to use any persistence system and we will use a class to serve our purpose for this demo application.

In the below class, we create several static blocks to hold book data. We create a list of books, a map of books and a map with a list of books.

Later we will see how we will convert list to json, map to json and a map with list to json.

package com.roytuts.rest.repo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.roytuts.rest.dto.Book;
public class RestResourceRepo {
	private static List<Book> BOOKS = new ArrayList<Book>();
	private static Map<String, Book> MAP = new HashMap<String, Book>();
	private static Map<String, List<Book>> MAP_LIST = new HashMap<String, List<Book>>();
	static {
		BOOKS.add(new Book(1l, "Java", "Gosling", "Java-123456"));
		BOOKS.add(new Book(2l, "REST Webservice", "REST Author", "REST-123456"));
		BOOKS.add(new Book(3l, "PHP", "PHP Author", "PHP-123456"));
		BOOKS.add(new Book(4l, "JavaScript", "JS Author", "JS-123456"));
		BOOKS.add(new Book(5l, "Database", "CJ Date", "DB-123456"));
	}
	static {
		MAP.put("book1", new Book(1l, "Java", "Gosling", "Java-123456"));
		MAP.put("book2", new Book(2l, "REST Webservice", "REST Author", "REST-123456"));
		MAP.put("book3", new Book(3l, "PHP", "PHP Author", "PHP-123456"));
		MAP.put("book4", new Book(4l, "JavaScript", "JS Author", "JS-123456"));
		MAP.put("book5", new Book(5l, "Database", "CJ Date", "DB-123456"));
	}
	static {
		List<Book> bookSet1 = new ArrayList<Book>();
		bookSet1.add(new Book(1l, "Java", "Gosling", "Java-123456"));
		bookSet1.add(new Book(2l, "REST Webservice", "REST Author", "REST-123456"));
		List<Book> bookSet2 = new ArrayList<Book>();
		bookSet2.add(new Book(3l, "PHP", "PHP Author", "PHP-123456"));
		bookSet2.add(new Book(4l, "JavaScript", "JS Author", "JS-123456"));
		bookSet2.add(new Book(5l, "Database", "CJ Date", "DB-123456"));
		MAP_LIST.put("b1", bookSet1);
		MAP_LIST.put("b2", bookSet2);
	}
	public static List<Book> getBooks() {
		return BOOKS;
	}
	public static Map<String, Book> getBookMap() {
		return MAP;
	}
	public static Map<String, List<Book>> getBookMapList() {
		return MAP_LIST;
	}
}

Creating REST Resource Class

Create a REST resource class to define our end-points at which we will query to get the desired results.

We annotate the resource class with @Path to give the base URI.

We define three methods to convert object into json string.

package com.roytuts.rest.resources;
import java.util.List;
import java.util.Map;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.google.gson.Gson;
import com.roytuts.rest.dto.Book;
import com.roytuts.rest.repo.RestResourceRepo;
@Path("/resource")
public class RestResources {
	@GET
	@Produces(MediaType.APPLICATION_JSON)
	@Path("getListAsJson")
	public Response getListAsJson() {
		Gson gson = new Gson();
		List<Book> books = RestResourceRepo.getBooks();
		String jsonString = gson.toJson(books);
		return Response.status(Response.Status.OK).entity(jsonString).build();
	}
	@GET
	@Produces(MediaType.APPLICATION_JSON)
	@Path("getMapAsJson")
	public Response getMapAsJson() {
		Gson gson = new Gson();
		Map<String, Book> books = RestResourceRepo.getBookMap();
		String jsonString = gson.toJson(books);
		return Response.status(Response.Status.OK).entity(jsonString).build();
	}
	@GET
	@Produces(MediaType.APPLICATION_JSON)
	@Path("getMapListAsJson")
	public Response getMapListAsJson() {
		Gson gson = new Gson();
		Map<String, List<Book>> books = RestResourceRepo.getBookMapList();
		String jsonString = gson.toJson(books);
		return Response.status(Response.Status.OK).entity(jsonString).build();
	}
}

Creating Junit Class

We would not deploy our application into external server. So we will create Junit class for testing different REST operations by deploying into the Grizzly server. The required library for Grizzly server has been added into the pom.xml file.

package com.roytuts.rest.resources;
import java.net.URI;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class RestResourceTest {
	private HttpServer httpServer;
	private WebTarget webTarget;
	private static final URI baseUri = URI.create("http://localhost:9090/rest-service/");
	@Before
	public void setUp() throws Exception {
		// create ResourceConfig from Resource class
		ResourceConfig rc = new ResourceConfig(RestResources.class);
		// create the Grizzly server instance
		httpServer = GrizzlyHttpServerFactory.createHttpServer(baseUri, rc);
		// start the server
		httpServer.start();
		// configure client with the base URI path
		Client client = ClientBuilder.newClient();
		webTarget = client.target(baseUri);
	}
	@After
	public void tearDown() throws Exception {
		// if you want to stop the server from the input through keyboard then uncomment
		// below two lines
		// System.out.println(String
		// .format("Application started.%nHit enter to stop it..."));
		// System.in.read();
		// stop the server
		httpServer.shutdown();
	}
	@Test
	public void testGetListAsJson() {
		Response response = webTarget.path("resource/getListAsJson").request(MediaType.APPLICATION_JSON)
				.accept(MediaType.APPLICATION_JSON).buildGet().invoke();
		System.out.println("JSON from List:");
		System.out.println();
		System.out.println(response.readEntity(String.class));
		System.out.println();
	}
	@Test
	public void testGetMapAsJson() {
		Response response = webTarget.path("resource/getMapAsJson").request(MediaType.APPLICATION_JSON)
				.accept(MediaType.APPLICATION_JSON).buildGet().invoke();
		System.out.println("JSON from Map:");
		System.out.println();
		System.out.println(response.readEntity(String.class));
		System.out.println();
	}
	@Test
	public void testGetMapListAsJson() {
		Response response = webTarget.path("resource/getMapListAsJson").request(MediaType.APPLICATION_JSON)
				.accept(MediaType.APPLICATION_JSON).buildGet().invoke();
		System.out.println("JSON from Map which contains List:");
		System.out.println();
		System.out.println(response.readEntity(String.class));
		System.out.println();
	}
}

Testing the Application

Run the above Junit test class as Junit test, you will see the below output in the console:

JSON from Map which contains List:
{"b2":[{"id":3,"title":"PHP","author":"PHP Author","isbn":"PHP-123456"},{"id":4,"title":"JavaScript","author":"JS Author","isbn":"JS-123456"},{"id":5,"title":"Database","author":"CJ Date","isbn":"DB-123456"}],"b1":[{"id":1,"title":"Java","author":"Gosling","isbn":"Java-123456"},{"id":2,"title":"REST Webservice","author":"REST Author","isbn":"REST-123456"}]}
JSON from Map:
{"book2":{"id":2,"title":"REST Webservice","author":"REST Author","isbn":"REST-123456"},"book1":{"id":1,"title":"Java","author":"Gosling","isbn":"Java-123456"},"book4":{"id":4,"title":"JavaScript","author":"JS Author","isbn":"JS-123456"},"book3":{"id":3,"title":"PHP","author":"PHP Author","isbn":"PHP-123456"},"book5":{"id":5,"title":"Database","author":"CJ Date","isbn":"DB-123456"}}
JSON from List:
[{"id":1,"title":"Java","author":"Gosling","isbn":"Java-123456"},{"id":2,"title":"REST Webservice","author":"REST Author","isbn":"REST-123456"},{"id":3,"title":"PHP","author":"PHP Author","isbn":"PHP-123456"},{"id":4,"title":"JavaScript","author":"JS Author","isbn":"JS-123456"},{"id":5,"title":"Database","author":"CJ Date","isbn":"DB-123456"}]

Source Code

download source code

That’s all. Thanks for reading.

Leave a Reply

Your email address will not be published. Required fields are marked *