Make it easy, test it easily: RESTful Web Services with JAVA and soapUI

In this article I will show how to build basic RESTful Web Services in JAVA for Web Application using JAX-RS: The Java API for RESTful Web Services and its open source implementation: Jersey together with XStream. I will also show how easy is to extend Jersey to work with your favorite XStream library and that testing Web Services can be a fun with the outstanding soapUI application.

Jersey, RestEasy, Restlet …

The are many libraries in JAVA which provide functionality for building RESTful services. Jersey and RestEasy are both JAX-RS implementations. Restlet is a very complex framework supporting lots of features available in many editions (including the one for Google App Engine). There are many factors that help decide which library to choose but the are not covered in this article. My choice is Jersey. But I don’t claim it is the best. I just like it.

Testing

Jersey provides Test Framework that allows you to test RESTful Web Services on a wide range of extensible containers, including Grizzly and Glasshfish. You can write tests using JUnit 4 by extending JerseyTest class in your test cases. If you want to find out more read this blog post describing usage scenario. For functional, integration and load testing I suggest using soapUI. soapUI is a great, open source tool for testing Web Services, including RESTful services. It lets you create test suites within  one click only. You can install it as an Eclipse plugin, but I prefer (and use) the standalone version.

soapUI workspace
soapUI workspace

Setting up an environment

  • Eclipse – Eclipse IDE for Java EE Developers that can be downloaded here: Eclipse downloads. Read my short review regarding its new functionality.
  • Web Server – Recently I have built web applications using Glassfish v3 Prelude application server, but for this tutorial Tomcat 6 is enough: Tomcat 6 download
  • Jersey – For this showcase I used Jersey 1.1.2-ea that implements JAX-RS 1.1. Download zip of Jersey that contains the Jersey jars, core dependencies and JavaDoc.
  • XStream – XStream is simple and fast object serialization library. Jersey natively supports Java for XML binding API (JAXB), but I will show how to extend it to support XStream – in case if you have your object model defined using XStream. You can download the latest version here: XStream download

Creating a project

Create a Dynamic Web Project in Eclipse, call it whatever you want and import all required libraries from Jersey and XStream:

  • jsr311-api-1.1.jar
  • jersey-core-1.1.2-ea.jar
  • jersey-server-1.1.2-ea.jar
  • jersey-client-1.1.2-ea.jar
  • xstream-1.3.1.jar
  • asm-3.1.jar
  • jettison-1.1.jar – used by XStream for JSON serialization
  • xpp3_min-1.1.4c.jar – used by XStream when unmarshaling
Eclipse - package explorer
Eclipse – package explorer

Object model classes

Let’s create object model using XStream annotations. In order to do it you can use this useful tutorial. Person object container with some data manipulations methods:

@XStreamAlias("people")
public class People {
	@XStreamImplicit
	List people = new ArrayList();
	public List getPeople() {
		return people;
	}
	public void setPeople(List people) {
		this.people = people;
	}
	public void add(Person person) {
		people.add(person);
	}
	public Person get(int index) {
		return people.get(index);
	}
	public void remove(int index) {
		people.remove(index);
	}
	public void modify(int id, Person person) {
		Person p = people.get(id);
		p.address = person.address;
		p.name = person.name;
	}
}

Person:

@XStreamAlias("person")
public class Person {
	String name;
	Address address;
	// methods omitted
}

And address:

public class Address {
	String street;
	String city;
	// methods omitted
}

Creating XStream provider

Extending Jersey to support XStream is easy. You need to create a class annotated with @Provider that marks it as a extension interface. The class must implement MessageBodyReader and MessageBodyWriter to provide Java object serialization and deserialization. In Jersey you can extend AbstractMessageReaderWriterProvider to write your own provider. The provider supports Java classes annotated with @XStreamAlias.

@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Consumes( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Provider
public class XStreamProvider extends
		AbstractMessageReaderWriterProvider

Please note the class is also annotated with @Produces (required by MessageBodyWriter) and @Consumes (required by MessageBodyReader) which means that it can read and write object to and from XML and JSON format.

Creating RESTful resource – PersonResource

@Path("person")
@Singleton
public class PersonResource {
	// class body omitted
}

The resource class is annotated with @Path that identifies the URI path that a resource class or class method will serve requests for. The other annotation is @Singleton which is not a part of JAX-RS API and marks the resource as a singleton (one instance per web application). You can mark any resource as singleton – including XStreamProvider, if needed. Get all

@GET
@Produces(MediaType.APPLICATION_XML)
@Path("/xml")
public People getAllAsXml() {
	return people;
}

@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/json")
public People getAllAsJson() {
	return people;
}

The above methods depend on the path used (person/xml or person/json) returns serialized People object. Creating @PUT – create new Person, @POST – modify existing record, @DELETE – delete record in JAX-RS is analogous:

@GET
@Produces(MediaType.APPLICATION_XML)
@Path("/xml/{id}")
public Person getAsXml(@PathParam("id") int i) {
	return people.get(i);
}

@PUT
@Consumes(MediaType.APPLICATION_XML)
@Path("/xml/add")
public void newFromXml(Person person) {
	add(person);
}

@POST
@Consumes(MediaType.APPLICATION_XML)
@Path("/xml/edit/{id}")
public void editXml(@PathParam("id") int id, Person person) {
	modify(id, person);
}

@DELETE
@Path("/person/{id}")
public void delete(@PathParam("id") int id) {
	remove(id);
}

That’s it. We have a resource that operates on Person Java object allowing: retrieval, creation, edition and removal. Easy. Tests omitted.

Deploying and running

To deploy the services to the server some small configuration needs to be done. Edit your web.xml file and add com.sun.jersey.spi.container.servlet.ServletContainer with init param com.sun.jersey.config.property.packages with packages that contain the resources. Remember, the XStreamProvider class is also a resource!

		Jersey
		com.sun.jersey.spi.container.servlet.ServletContainer

com.sun.jersey.config.property.packages
org.kolorobot.example.resources

		Jersey
		/api/*

Running the application in Eclipse:

Running the project on Glassfish
Running the project on Glassfish

Creating soapUI WADL project

Jersey exposes WADL file out-of-the-box under the following URL: /api/application.wadl (/api/* is a Jersey servlet mapping path, see servlet mapping in web.xml). I use this URL to create a soapUI project (the web server must be running of course). Run the soapUI and create new project. In the initial WSDL/WADL field type the URL of application WADL mentioned before:

soapUI new project definition with initial WADL
soapUI new project definition with initial WADL

Click OK. The project is created, all methods are ready to be tested: soapUI creates default requests for all methods found in the WADL.

soapUI project details
soapUI project details

By using soapUI you can browse content of the WADL file, you can test you requests, you can create test suites, load cases and many more.

Executing requests in soapUI

Find default requests for getAllAsXml and getAllAsJson methods, open and execute them. You should see the output of a request as in the following image: soap_req1 Similarly, you can verify other methods. Isn’t it just simple?

soapUI – next steps

Having defined default requests in your project it is time to create a test suite (soapUI generates it automatically, if you wish). Create test cases, test steps, load tests and make sure your application is working perfectly. soapUI is a very popular tool, it is also very easy to learn. I suggest reading the documentation on soapUI web site to get familiar with its wide range of features.

Summary

I used to work with soapUI for testing SOAP Web Services, and I really enjoyed it. I think, the tool can be easily used for testing RESTful web services too, and now creating Web Services (not only RESTful) is a piece of cake. Maybe it is the right time to focus more on testing them? What do you think?

Download the application

The web application used in this article can be downloaded here: jersey-with-xstream. It contains Java source files. Share your opinions and experience with us by leaving a comment  or meet us on Twitter: @GOYELLO.

Tags: ,

Aspire Blog Team

Aspire Systems is a global technology services firm serving as a trusted technology partner for our customers. We work with some of the world's most innovative enterprises and independent software vendors, helping them leverage technology and outsourcing in our specific areas of expertise. Our services include Product Engineering, Enterprise Solutions, Independent Testing Services and IT Infrastructure Support services. Our core philosophy of "Attention. Always." communicates our belief in lavishing care and attention on our customers and employees.

10 comments

  1. Hi Rafal,

    When I tested the sample using POST and PUT, I got the error below. Could you help me out with this issue?

    <h1>HTTP Status 415 – </h1>


    type Status report

    message

    description The server refused this request because the request entity is in a format not supported by the requested resource for the requested method ().

    Thanks, Deniel

  2. Probably, when you try to send a request format of the body message is incorrect – it must be valid Person object as XML or JSON. The project itself does not contain tests, but you can do this: use GET to get Person as XML or JSON, and then using this format try to create PUT/POST message. Let me know if it works.

    1. HI.. do you have any articles for file upload? pls. help me out… I need ASAP..

  3. It looks good,I have learn a recruit!
    Recently,I found an excellent online store, the “http://www.air-jordan-18.com are completely various, good quality and cheap price,it’s worth buying!

  4. Hhe article's content rich variety which make us move for our mood after reading this article. surprise, here you will find what you want! Recently, I found some wedsites which commodity is research-laboratory colorful of fashion. Such as that worth you to see. Believe me these websites won’t let you down.

  5. hello.thanks for introducing web services to us.I am trying to implement this tutorial while doing so when I create the XstreamProvider class…
    AbstractMessageReaderWriterProvider

    gives me error stating all xml nodes cannot be resolved eg:object,width,height cannot be resolved etc….

Comments are closed.