‘rapa’ With Jersey

rapa – ActiveResource like RESTClient for java

[Visit: http://code.google.com/p/rapa/%5D

Introduction

The following is a very simple implementation of Rapa Client communicating to the REST web service which was developed using Jersey. Most part of this document is self-explanatory and the code can be just copied and run from any windows or linux box with Java 5 or above installed.

The rapa client basically tries to communicate to a REST service deployed on the Grizzly server (comes as part of Jersey download) in order to do the CRUD operations on a Customer entity.

For the rapa client to be able to communicate to the REST service, the following are the simple steps needs to be followed in a sequence.

First, we need to build a REST service using Jersey which exposes API’s for performing the CRUD operation on Customer entities.

Second, the developed web service has to be deployed.

And finally, a rapa client is used to perform the CRUD operations hiding all the complexities of connecting and performing various operation on the deployed web service.

Software’s Required

Java files involved

  1. Customer.java – Entity.
  2. CustomerService.java – Service Provider.
  3. RestServiceDeployer.java – Web Service Deployer.
  4. RapaClientForJersey.java – Rapa Client
  • Customer.java and CustomerService.java were the two classes used for creating the REST service using Jersey.
  • RestServiceDeployer.java is a simple code that helps us to deploy the service on the Grizzly’s server.
  • RapaClientForJersey.java is used for communicating the web service and perform operations using the exposed APIs.

Now let’s into details of how the implementation is done.

Implementing REST Service using Jersey

Customer.java

/* Entity representing the Customer.
* This class also holds the container to store the newly
* created/existing customers */
package org.restinjersey.sample.resource;

import java.util.HashMap;
import java.util.Map;

import javax.xml.bind.annotation.XmlRootElement;

import org.rest.rapa.resource.Resource;

@XmlRootElement
public class Customer implements Resource {
//container to hold the customers.
public static Map<Integer, Customer> CUSTOMERS_STORE
= new HashMap<Integer, Customer>();

private int id;
private String name;

public Customer() {}

public static Customer getCustomer(int id) {
return CUSTOMERS_STORE.get(id);
}

public static void addCustomer(String name) {
Customer shoe = new Customer();
shoe.setId(CUSTOMERS_STORE.size() + 1);
shoe.setName(name);
CUSTOMERS_STORE.put(shoe.getId(), shoe);
}

public int getId() {
return id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String toJson() {
String result = “{ ‘id’ : ” + this.id + ” , “;
result += ” ‘name’ : ” + this.name + ” }”;
return result;
}

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

}

CustomerService.java

/* Class implementing REST Web Service using Jersey
Basically exposing the CRUD operation for the Customer  */

package org.restinjersey.sample.resource;

import java.io.InputStream;
import java.io.StringWriter;

import javax.ws.rs.ConsumeMime;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.ProduceMime;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

@Path(“/”)
public class CustomerService {

@GET
@Path(“/customers/{id}.xml”)
@ProduceMime(“text/xml”)
public String getCustomerById(@PathParam(“id”) int id) {
Customer customer = Customer.getCustomer(id);
validateCustomer(customer);
return encodeCustomerInXML(customer);
}

@POST
@Path(“/customers.xml”)
@ConsumeMime(“text/xml”)
public Response addCustomer(InputStream inputStream) {
Customer customer = extractCustomerFromXML(inputStream);
validateCustomer(customer);
Customer.addCustomer(customer.getName());
return Response.status(Status.CREATED).build();
}

@DELETE
@Path(“/customers/{id}.xml”)
public Response deleteCustomer(@PathParam(“id”) int id) {
Customer customer = Customer.getCustomer(id);
validateCustomer(customer);
Customer.CUSTOMERS_STORE.remove(id);
return Response.status(Status.OK).build();
}

@PUT
@Path(“/customers/{id}.xml”)
@ConsumeMime(“text/xml”)
public Response updateCustomer(InputStream inputStream) {
Customer obtCustomer = extractCustomerFromXML(inputStream);
validateCustomer(obtCustomer);
Customer.getCustomer(obtCustomer.getId()).setName(obtCustomer.getName());
return Response.status(Status.ACCEPTED).build();
}

private String encodeCustomerInXML(Customer customer) {
StringWriter writer;
try {
Marshaller marshaller
= JAXBContext.newInstance(Customer.class).createMarshaller();
writer = new StringWriter();
marshaller.marshal(customer, writer);
} catch (JAXBException e) {
throw new WebApplicationException(Status.INTERNAL_SERVER_ERROR);
}
return writer.toString();
}

private Customer extractCustomerFromXML(InputStream is) {
try {
Unmarshaller unMarshaller
= JAXBContext.newInstance(Customer.class).createUnmarshaller();
return (Customer)unMarshaller.unmarshal(is);
}
catch (JAXBException e) {
throw new WebApplicationException(Status.INTERNAL_SERVER_ERROR);
}
}

private void validateCustomer(Customer customer) {
if(customer == null) {
throw new WebApplicationException(Status.NOT_FOUND);
}
}
}

Deploying the Service using Jersey’s in-built Grizzly Server

RESTServiceDeployer.java

/* Class used for deploying the REST Web Service on Jersey's in-built Grizzly Server. */

package org.restinjersey.sample.main;

import java.util.HashMap;
import java.util.Map;

import com.sun.grizzly.http.SelectorThread;
import com.sun.jersey.api.container.grizzly.GrizzlyWebContainerFactory;

public class RESTServiceDeployer {

public static final String BASE_URI = “http://localhost:9998/&#8221;;

public static void main(String[] args) throws Exception {
Map<String, String> initParams = new HashMap<String, String>();
initParams.put(“com.sun.jersey.config.property.packages”,
“org.restinjersey.sample.resource”);

System.out.println(“Starting Grizzly….”);

SelectorThread threadSelector
= GrizzlyWebContainerFactory.create(BASE_URI, initParams);

System.out.println(String.format(“Jersey app started with WADL available
at%sapplication.wadln” + “Hit enter to stop it…”, BASE_URI));

System.in.read();
threadSelector.stopEndpoint();
System.exit(0);
}
}

Using Rapa client to access the REST Service

RapaClientForJersey.java

/* Client Class used for used for communicating the REST Web Service. */

package org.restinjersey.sample.main;

import org.rest.rapa.RestClientException;
import org.rest.rapa.RestClientWrapper;
import org.restinjersey.sample.resource.Customer;
public class RapaClientForJersey {

public static final String DEPLOYED_SERVICE_URI = “http://localhost:9998/customers&#8221;;

public static void main(String[] args) throws RestClientException {

RestClientWrapper<Customer> client =
new RestClientWrapper<Customer>(DEPLOYED_SERVICE_URI, “”, “”,
“localhost”, 9000);

//create new customer
Customer customer = new Customer();
customer.setName(“New, Client”);
client.save(customer);

//update existing customer
customer.setName(“Updated, Client”);
client.update(customer);

//view existing customer details
Customer obtainedCustomer = client.getById(1,
org.restinjersey.sample.resource.Customer.class);

System.out.println(String.format(“Customer[id: %s, name: %s]”,
obtainedCustomer.getId(), obtainedCustomer.getName()));

//delete existing customer
client.delete(customer);
}
}

Conclusion

Hope the code was simple and self-explanatory. 🙂 Before concluding this post, there are some points to be noted.

  • RapaClient throws RestClientException if any of the operations were unsuccessful.
  • Make sure the deployment of REST services is successfully done before executing the Rapa client.

If you have any feedback/suggestions please let us know. We will be very much glad to respond to your queries/feedback.

Advertisements

About this entry