How to write a simple RESTful web service using Jersey (Part 3)?

In the previous 2 parts, we saw how to read something via RESTful web service. Here we are going to see how to pass in data from client to the web service? In our “Hello, World” example, what if I want to display a custom greeting instead of a “Hello”?

Create the method that takes in user input parameter.

@GET
@Produces({MediaType.TEXT_PLAIN})
@Path("/plain")
public String getPlain(@DefaultValue("Hello") @QueryParam("greeting") String greeting) {
	return greeting + " World!!!";
}

That’s it. Now try adding custom greeting to your local URL as shown below:
http://localhost:8080/PlayArea-1.0/helloworldapp/helloworldresources/plain?greeting=Welcome

As you can see, the custom parameter “greeting” is passed in via the URL as “?greeting=Welcome” (Multiple parameters can be passed in separated by &). On the server side, the method which processes this request takes in a method parameter annotated with @QueryParam(“greeting”). JAX-RS binds the query parameter value from URL to this method parameter variable. A default value can be assigned to this parameter via @DefaultValue annotation.

Using HTTP, there are several ways to pass data from client to the service. When to use what is a separate topic for another day. For now, let us stick the example above which uses technique #1.

  1. via URL query parameter
  2. via URL path
  3. via HTTP Header
  4. via HTTP POST body
  5. via cookie

JAX-RS provides various mechanisms to process the data from client requests in your service. Here are few:

  1. @QueryParam – to read query parameters from URL
  2. @HeaderParam – to read data from HTTP header
  3. @FormParam – to read data from HTTP POST form
  4. @PathParam – to read from the URL path
  5. @MatrixParam – to read from the URI matrix values
  6. @CookieParam – to read cookie data sent from the client
  7. @Context UriInfo – to get all the URI related information via a single object
  8. @Context HttpHeaders – to read all the header information via a single object
  9. @BeanParam – to read data from one of the aforementioned ways and bind it to a custom bean.
  10. MultivaluedMap<String, String> formParams – to read all the form parameters as a map without using annotations

How to write a simple RESTful web service using Jersey (Part 2)?

In Part 1, we saw how to create a simple REST service that returns “Hello World!!!” as a plain text. In this part, we are going to see how to transform a Java object into XML/JSON based on user request.

Prerequisites

  • Familiarity with the code in Part 1
  • Include the Jackson library for JSON tranformation
 'com.fasterxml.jackson.core:jackson-core:2.2.3'
 'com.fasterxml.jackson.core:jackson-databind:2.2.3'

Step 1: Create a domain/POJO Java class named “HelloWorld.java”
Description: Please note that the POJO class is annotated with JAX-B annotation. JAX-B helps transform the Java class to XML by linking a Java type like String to XML type, in this case xsd:string.

package webservices.ch01;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "greet")
public class HelloWorld {
    private String greeting = "Hello";
    private String receiver = "World";

    public HelloWorld() {
    }

    public HelloWorld(String greeting, String receiver) {
        this.greeting = greeting;
        this.receiver = receiver;
    }

    public String getGreeting() { return greeting; }

    public void setGreeting(String greeting) { this.greeting = greeting; }

    public String getReceiver() { return receiver; }

    public void setReceiver(String receiver) { this.receiver = receiver; }

    @Override
    public String toString() {
        return greeting + " " + receiver + "!!!";
    }
}

Step 2: Add getXML() method in HelloWorldResources.java 
Description: Using JAXB, the HelloWorld object is transformed into an XML document. Note here the return data format is annotated as MediaType.TEXT_XML, and the method return type is JAXBElement.

@GET
@Produces({MediaType.TEXT_XML})
@Path("/xml")
public JAXBElement<HelloWorld> getXML() {
	return new JAXBElement<>(new QName("helloworldxml"), HelloWorld.class, new HelloWorld()) ;
}

Step 3: Add getJson() method in HelloWorldResources.java
Description: Using the Jackson library, a new HelloWorld is converted into a JSON string. Return data format is annotated as MediaType.APPLICATION_JSON.

@GET
@Produces({MediaType.APPLICATION_JSON})
@Path("/json")
public String getJson() throws JsonProcessingException {
	final HelloWorld helloWorld = new HelloWorld("Hi", "Buddy");
	return new ObjectMapper().writeValueAsString(helloWorld);
}

Step 4: Try the URLs now

URL: http://localhost:8080/PlayArea-1.0/helloworldapp/helloworldresources/xml

XML Output:

<helloworldxml>
   <greeting>Hello</greeting>
   <receiver>World</receiver>
</helloworldxml>

URL: http://localhost:8080/PlayArea-1.0/helloworldapp/helloworldresources/json

JSON Output:

{"greeting":"Hi","receiver":"Buddy"}

(Source code for the above can be found in https://github.com/fizalihsan/PlayArea/)

How to write a simple RESTful web service using Jersey (Part 1)?

In this series, I’m going to show you how to write simple RESTful web services using the JAX-RS reference implementation named Jersey (and other implementations of JAX-RS, if time permits).

In part 1, we are going to see how to write a “Hello World” RESTful service that just returns “Hello World!!!” in plain text.

As a prerequisite, you need the below before executing it in your local PC.

  • A servlet container (like Tomcat) or a Java Application Server (like Glassfish) is up and running in your machine under port 8080.
  • Download following libraries from Jersey homepage  and copy under /WEB-INF/lib

‘javax.ws.rs:javax.ws.rs-api:2.0’
‘org.glassfish.jersey.containers:jersey-container-servlet:2.4’
‘org.glassfish.jersey.core:jersey-server:2.4’

Step 1: Add the below lines in web.xml

Description: By adding the below lines, Jersey ServletContains scans for implementation of Jersey Application classes which is shown in step 2.

<servlet>
	<servlet-name>jersey</servlet-name>
	<servlet-class> com.glassfish.jersey.servlet.ServletContainer </servlet-class>
	<!-- load an instance of the Jersey ServletContainer during the WAR bootstrap process; the critical role of the
	ServletContainer is to scan the deployed WAR file for Jersey Application classes. -->
	<load-on-startup>1</load-on-startup>
</servlet>

Step 2: Implement the Jersey Application class

Description: Method getClasses() iterates through the list of resource classes found. In our case, there is only one such class called “HelloWorldResources”.

package webservices;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import java.util.HashSet;
import java.util.Set;

@ApplicationPath("/helloworldapp")
public class HelloWorldApplication extends Application {
    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> set = new HashSet<>();
        set.add(HelloWorldResources.class);
        return set;
    }
}

Step 3: Implement the class that serves the resources

Description: @Path annotation at class level says that all the resources in this class is accessed by prefixing the path “/helloworldresources”.

The method getPlain() serves a resource by the name “/plain” in data format “text/plain” via HTTP GET request.

package webservices;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/helloworldresources")
public class HelloWorldResources {
    @GET
    @Produces({MediaType.TEXT_PLAIN})
    @Path("/plain")
    public String getPlain() {
        return "Hello World!!!";
    }
}

Step 4: Create WAR file and deploy

Create WAR file (named PlayTest-1.0.war) and deploy in the server. Now enter the below URL in your browser, and voila, “Hello World!!!” is displayed in plain text.

http://localhost:8080/PlayArea-1.0/helloworldapp/helloworldresources/plain

(Source code for the above can be found in https://github.com/fizalihsan/PlayArea/)