Goal

In my last article I built a simple hello world Rest service, now i want to introduce more examples trying to light up various aspects of restful service.

Used technologies

JDK 1.8
Maven 3.2
Maven dependencies: jersey 1.18. + jackson.jaxrs + jackson-xc + junit

1. pom.xml

		<dependency>
			<groupId>com.sun.jersey</groupId>
			<artifactId>jersey-bundle</artifactId>
			<version>1.18.4</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-xc</artifactId>
			<version>1.9.13</version>
		</dependency>
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-jaxrs</artifactId>
			<version>1.9.13</version>
		</dependency>

2. Model: Tutorial

package com.wstutorial.rest;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Tutorial {
	private long id ;
	private String name;
	private String author;

	public Tutorial() {
	}

	public Tutorial(long id , String name, String author) {
		this.id = id;
		this.name = name;
		this.author = author;
	}
	..
}

3. Resource: TutorialResource

package com.wstutorial.rest;

import java.util.List;
import javax.ws.rs.*;
import javax.ws.rs.core.*;

@Path("/")
public class TutorialResource {

	@GET
	@Path("tutorials")
	@Produces(MediaType.APPLICATION_JSON)
	public Response tutorials() {
		List tutorials = TestData.allTutorials();
		GenericEntity> tutList = new GenericEntity>(tutorials) {};

		return Response.ok(tutList).build();
	}

	@GET
	@Path("tutorials/{id}")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getTutorial(@PathParam("id") long id) {
		Tutorial tutorial = TestData.tutorialById(id);
		return Response.ok(tutorial).build();
	}
	
	@POST
	@Path("tutorials")
	@Produces(MediaType.APPLICATION_JSON)
	public Response addTutorial(Tutorial tutorial) {
		if (tutorial == null) {
			return Response.status(400).entity("Tutorial should not be null").build();
		}

		return Response.status(201).build();
	}
	
	@PUT
	@Path("tutorials")
	@Produces(MediaType.APPLICATION_JSON)
	public Response updateTutorial(Tutorial tutorial) {
		return Response.status(200).build();
	}
	
	@DELETE
	@Path("tutorials/{id}")
	@Produces(MediaType.APPLICATION_JSON)
	public Response deleteTutorial(@PathParam("id") long id) {
		System.out.println("ID " + id + " was deleted");
		return Response.status(202).build();
	}

}

Where are HEAD and OPTIONS methods!
By default the JAX-RS runtime will automatically support the methods HEAD and OPTIONS, if not explicitly implemented. For HEAD the runtime will invoke the implemented GET method (if present) and ignore the response entity (if set). A response returned for the OPTIONS method depends on the requested media type defined in the 'Accept' header. The OPTIONS method can return a response with a set of supported resource methods in the 'Allow' header or return a WADL document.

4. Rest Starter

package com.wstutorial.rest;

import com.sun.jersey.api.container.httpserver.HttpServerFactory;
import com.sun.net.httpserver.HttpServer;

public class StartRestServer {
	public static void main(String[] args) {
		HttpServer server;
		try {
			server = HttpServerFactory.create( "http://localhost:10080/api" );
			server.start();
		}catch (Exception e) {
			System.out.println("Errormessage : " + e.getMessage());
		}

	}
}

4. Call the url

To obtain all tutorials: http://localhost:10080/api/tutorials
Just only one specific tutorial: http://localhost:10080/api/tutorials/2

5. Using curl

curl -i http://localhost:10080/api/tutorials
curl -i http://localhost:10080/api/tutorials/1
curl -H "Content-Type: application/json" -X POST -d '{"author":"Adam snake","id":"1","name":"Python Basics"}' http://localhost:10080/api/tutorials
curl -H "Content-Type: application/json" -X PUT -d '{"author":"Adam changed","id":"1","name":"Python Basics"}' http://localhost:10080/api/tutorials
curl -X DELETE http://localhost:10080/api/tutorials/1
curl -X HEAD http://localhost:10080/api/tutorials/1
curl -X OPTIONS http://localhost:10080/api

6. Jax-rs Clients

package com.wstutorial.rest;

import static org.junit.Assert.*;

import java.util.List;

import javax.ws.rs.core.MediaType;

import org.codehaus.jackson.jaxrs.JacksonJsonProvider;
import org.junit.Test;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.GenericType;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;

public class TestClient {

	private String endpoint = "http://localhost:10080/api";

	@Test
	public void testGetAll() {

		ClientConfig cfg = new DefaultClientConfig();
		cfg.getClasses().add(JacksonJsonProvider.class);
		Client client = Client.create(cfg);

		List tutorials = client.resource(endpoint + "/tutorials")
				.get(new GenericType>() {});
		assertTrue(tutorials.size() == 3);
	}

	@Test
	public void testGetOne() {
		String url = endpoint + "/tutorials/1";
		Tutorial tutorial = Client.create().resource(url).get(Tutorial.class);
		assertTrue(tutorial.getId() == 1);
	}

	@Test
	public void testPost() {
		WebResource wrs = Client.create().resource(endpoint + "/tutorials");
		Tutorial tutorial = new Tutorial(4, "Rest with jersey", "will john");
		ClientResponse response = wrs.post(ClientResponse.class, tutorial);
		assertTrue(response.getStatus() == 201);
	}

	@Test
	public void testPut() {
		WebResource wrs = Client.create().resource(endpoint + "/tutorials");
		Tutorial tutorial = new Tutorial(4, "Rest with jersey", "John Doe");
		ClientResponse response = wrs.put(ClientResponse.class, tutorial);
		assertTrue(response.getStatus() == 200);
	}

	@Test
	public void testHead() {
		WebResource wrs = Client.create().resource(endpoint + "/tutorials/1");
		ClientResponse response = wrs.type(MediaType.APPLICATION_JSON).head();
		assertTrue(response.getStatus() == 200);
	}

	@Test
	public void testDelete() {
		WebResource wrs = Client.create().resource(endpoint + "/tutorials/4");
		ClientResponse response = wrs.delete(ClientResponse.class);
		assertTrue(response.getStatus() == 202);
	}

	@Test
	public void testOptions() {
		WebResource wrs = Client.create().resource(endpoint + "/tutorials");
		ClientResponse response = wrs.options(ClientResponse.class);
		assertTrue(response.getAllow().contains("GET"));
	}
}

References

  • Jersey