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).

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, JDK 1.7, Maven 2.x, Jersey

Step 1. Create maven project in Eclipse with the below information

Group Id: com.roytuts
Artifact Id: rest-service

Step 2. Modify the pom.xml file to use jar libraries

<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>rest-service</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>rest-service Maven Webapp</name>
    <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>
    </dependencies>
    <build>
        <finalName>rest-service</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Step 3. Modify web.xml file to use the jersey servlet

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
    <display-name>REST Service</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>

Step 4. Create a REST resource class as shown below

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.utils.RestResourceUtils;

@Path("/resource")
public class RestResources {

  @GET
  @Produces(MediaType.APPLICATION_JSON)
  @Path("getListAsJson")
  public Response getListAsJson() {
    Gson gson = new Gson();
    List<Book> books = RestResourceUtils.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 = RestResourceUtils.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 = RestResourceUtils.getBookMapList();
    String jsonString = gson.toJson(books);
    return Response.status(Response.Status.OK).entity(jsonString).build();
  }

}

Step 5. Create utility class for data population

package com.roytuts.rest.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.roytuts.rest.dto.Book;

public class RestResourceUtils {

  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;
  }

}

Step 6. Create a POJO class which defines Book

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;
  }

  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public String getTitle() {
    return title;
  }

  public void setTitle(String title) {
    this.title = title;
  }

  public String getAuthor() {
    return author;
  }

  public void setAuthor(String author) {
    this.author = author;
  }

  public String getIsbn() {
    return isbn;
  }

  public void setIsbn(String isbn) {
    this.isbn = isbn;
  }

}

Step 7. Create Junit class for testing different REST operations

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 RestResourcesTest {

  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(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(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(response.readEntity(String.class));
    System.out.println();
  }

}

Step 8. Run the above test class, you will see the below output in the console

Jun 03, 2015 11:27:00 AM org.glassfish.jersey.server.ApplicationHandler initialize
INFO: Initiating Jersey application, version Jersey: 2.6 2014-02-18 21:52:53...
Jun 03, 2015 11:27:01 AM org.glassfish.grizzly.http.server.NetworkListener start
INFO: Started listener bound to [localhost:9090]
Jun 03, 2015 11:27:01 AM org.glassfish.grizzly.http.server.HttpServer start
INFO: [HttpServer] Started.
JSON from Map which contains List
{"b1":[{"id":1,"title":"Java","author":"Gosling","isbn":"Java-123456"},{"id":2,"title":"REST Webservice","author":"REST Author","isbn":"REST-123456"}],"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"}]}

Jun 03, 2015 11:27:02 AM org.glassfish.grizzly.http.server.NetworkListener shutdownNow
INFO: Stopped listener bound to [localhost:9090]
Jun 03, 2015 11:27:02 AM org.glassfish.grizzly.nio.GracefulShutdownRunner run
WARNING: GRIZZLY0032: Primary shutdown thread interrupted.  Forcing transport termination.
Jun 03, 2015 11:27:02 AM org.glassfish.jersey.server.ApplicationHandler initialize
INFO: Initiating Jersey application, version Jersey: 2.6 2014-02-18 21:52:53...
Jun 03, 2015 11:27:02 AM org.glassfish.grizzly.http.server.NetworkListener start
INFO: Started listener bound to [localhost:9090]
Jun 03, 2015 11:27:02 AM org.glassfish.grizzly.http.server.HttpServer start
INFO: [HttpServer-1] Started.
JSON from Map
{"book5":{"id":5,"title":"Database","author":"CJ Date","isbn":"DB-123456"},"book3":{"id":3,"title":"PHP","author":"PHP Author","isbn":"PHP-123456"},"book4":{"id":4,"title":"JavaScript","author":"JS Author","isbn":"JS-123456"},"book1":{"id":1,"title":"Java","author":"Gosling","isbn":"Java-123456"},"book2":{"id":2,"title":"REST Webservice","author":"REST Author","isbn":"REST-123456"}}

Jun 03, 2015 11:27:02 AM org.glassfish.grizzly.http.server.NetworkListener shutdownNow
INFO: Stopped listener bound to [localhost:9090]
Jun 03, 2015 11:27:02 AM org.glassfish.grizzly.nio.GracefulShutdownRunner run
WARNING: GRIZZLY0032: Primary shutdown thread interrupted.  Forcing transport termination.
Jun 03, 2015 11:27:02 AM org.glassfish.jersey.server.ApplicationHandler initialize
INFO: Initiating Jersey application, version Jersey: 2.6 2014-02-18 21:52:53...
Jun 03, 2015 11:27:02 AM org.glassfish.grizzly.http.server.NetworkListener start
INFO: Started listener bound to [localhost:9090]
Jun 03, 2015 11:27:02 AM org.glassfish.grizzly.http.server.HttpServer start
INFO: [HttpServer-2] Started.
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"}]

Jun 03, 2015 11:27:02 AM org.glassfish.grizzly.http.server.NetworkListener shutdownNow
INFO: Stopped listener bound to [localhost:9090]
Jun 03, 2015 11:27:02 AM org.glassfish.grizzly.nio.GracefulShutdownRunner run
WARNING: GRIZZLY0032: Primary shutdown thread interrupted.  Forcing transport termination.

That’s all. Thanks for reading.

Tags:

I am a professional Web developer, Enterprise Application developer, Software Engineer and Blogger. Connect me on Roy Tutorials | TwitterFacebook Google PlusLinkedin | Reddit | Email Me

Leave a Reply

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