Develop Restful application with RESTeasy

May 7 20096 Commented

Categorized Under: Engroup, Java, Software Engineer, Technology, Testing

Web service is complicated, to understand web service you must know SOAP, WSDL, XML schema etc. CORBA is even more completed than Web service. Our team have many years experience of developing web services by using various libraries like Axis, XFire and Cxf .We spent nearly month to understand and practice each type of SOAP message, parts of WSDL and tricks to keep the interoperability follows WS-I guidelines. However, we only need several days to learn REST and practice it in our project. Recently, we have a task of providing the API allows third-party application could get data from our application, though we have many experience in web service but we would like to investigate REST option. After several days for evaluating, REST is our choice. We are very pleased with the simplicity of REST - a lightweight web service, simple and powerful. In java world, RESTeasy (http://www.jboss.org/resteasy/) provides frameworks to help you build Restful Web Services. With RESTeasy, we could deploy Restful solution without impacting to existing code-base, ease to write unit test and ease to extend its functionalities, and the last RESTeasy documentation is comprehensive - you can learn to use RESTeasy in several hours only.

Our sample project is an existing application that uses Spring as IOC container, we would like to expose service method to third-party applications. We have the interface and its implementation already.

public interface FileSystemService {
    SimpleFile getFileByPath(String filePath);
    ...
}

Enable Restful service

The request /filesystem/getFile/<path of file> will return the file information if it is existed. To make it happen, we add java REST annotation to our service:

@Path("/filesystem")
public interface FileSystemService {
    @GET
    @Path("/getFile/{filePath:.*}")
    @Produces("application/xml")
    SimpleFile getFileByPath(@PathParam("filePath") String filePath);
    ...
}

Because the path of file may contains the '/' character, '/' is also the special characters of Http request, thus in line 4 we must use regular expression * to tell RESTeasy that all requests starts with /getFille is mapped to method getFileByPath (for example: /getFile/content/A or /getFile/content/A/B/C is valid path). @Produces("application/xml") annotation tells RESTeasy that the output must be in XML form.

Content marshalling/unmarshalling

Class SimpleFile is the complex type, to force RESTeasy produces XML data to client you must instruct RESTeasy how to marshal SimpleFile class.

@XmlRootElement(namespace="http://www.esofthead.com/engroup")
public class SimpleFile extends Content {
    private long size;
        ...
}

Installation

It is easy to install RESTeasy in java application, read the Installation section of RESTeasy documentation. Read more Spring integration section if you want to integrate RESTeasy with Spring. And we finish enable RESTful support in our Java application! Like its name, it is easy to deploy Restful solution by using RESTeasy.

Unit test

After all above tasks, it is time to look unit test solution. RESTeasy provides two approaches to write unit test:

  • Embedded Container:RESTeasy packages TJWS embeddable servlet container with JAX-RS. You can start the embedded server in your unit test and use Apache HttpClient to test your code. See the sample in attachment files for detail.
  • Server side - Mock framework:If you are not comfortable with starting the embedded server and would like a simpler solution, RESTeasy Mock framework would be a good option.

    Create Dispatcher mock object and integrate RESTeasy with Spring

    dispatcher = MockDispatcherFactory.createDispatcher();
    SpringBeanProcessor processor = new SpringBeanProcessor(dispatcher,
                    null, null);
    factory = new ClassPathXmlApplicationContext("ecm-context-test.xml");
    factory.addBeanFactoryPostProcessor(processor);
     
    SpringResourceFactory noDefaults = new SpringResourceFactory(
                    "fileSystemService", factory, FileSystemService.class);
    dispatcher.getRegistry().addResourceFactory(noDefaults);

    Send the request and test expected output

    MockHttpRequest request = MockHttpRequest
                    .get("/filesystem/getFile/content/A");
    MockHttpResponse response = new MockHttpResponse();
    dispatcher.invoke(request, response);
     
    Assert.assertEquals(HttpServletResponse.SC_OK, response.getStatus());
    String responseBodyAsString = response.getContentAsString();
     
    JAXBContext jaxbContext = JAXBContext.newInstance(SimpleFile.class);
    Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
    SimpleFile resultFile = (SimpleFile) unmarshaller
                    .unmarshal(new StringReader(responseBodyAsString));
     
    Assert.assertEquals(ContentConstants.FILE_ROOT_PATH + "/A", resultFile
                    .getPath());

    The result of request method is a XML string, the result of marshaling SimpleFile object to XML. To avoid testing base on XML data, we use JAXB to unmarshal XML data to SimpleFile object and validate data on this POJO.

I include two samples unit test for two approaches FileSystemRestTest-EmbeddedServer.java and FileSystemRestTest-MockFramework.java.This unit test sample is gotten from our engroup ECM module (you can get the Engroup product at http://esofthead.com/node/25), the unit test can not run because it lacks some classes of Engroup ECM module (this module is released in upcoming Engroup 1.5 version) but it provides the detail how to write unit test with RESTeasy.

Share and Enjoy:
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • BarraPunto
  • Bitacoras.com
  • blinkbits
  • BlinkList
  • blogmarks
  • BlogMemes
  • BlogMemes Cn
  • BlogMemes Fr
  • BlogMemes Jp
  • BlogMemes Sp
  • Blogosphere News
  • Blogsvine
  • blogtercimlap
  • Book.mark.hu
  • Bumpzee
  • co.mments
  • connotea
  • De.lirio.us
  • Design Float
  • DotNetKicks
  • DZone
  • eKudos
  • email
  • Fark
  • Faves
  • feedmelinks
  • Fleck
  • Furl
  • GeenRedactie
  • Global Grind
  • Gwar
  • Haohao
  • HealthRanker
  • Hemidemi
  • Identi.ca
  • IndianPad
  • Internetmedia
  • kick.ie
  • Kirtsy
  • laaik.it
  • Leonaut
  • LinkaGoGo
  • LinkArena
  • LinkedIn
  • Linkter
  • Live
  • Ma.gnolia
  • Meneame
  • MisterWong
  • MisterWong.DE
  • muti
  • MyShare
  • MySpace
  • N4G
  • Netvibes
  • Netvouz
  • NewsVine
  • NuJIJ
  • Ping.fm
  • PlugIM
  • Pownce
  • ppnow
  • Print
  • Propeller
  • Ratimarks
  • Rec6
  • Reddit
  • SalesMarks
  • Scoopeo
  • scuttle
  • Segnalo
  • Shadows
  • Simpy
  • Slashdot
  • Smarking
  • Socialogs
  • SphereIt
  • Spurl
  • StumbleUpon
  • Symbaloo
  • Taggly
  • TailRank
  • Technorati
  • ThisNext
  • Tipd
  • Tumblr
  • TwitThis
  • Upnews
  • Webnews.de
  • Webride
  • Wikio
  • Wikio FR
  • Wikio IT
  • Wists
  • Wykop
  • Xerpi
  • Yahoo! Buzz
  • YahooMyWeb
  • Yigg

6 Responses to “Develop Restful application with RESTeasy”

  1. I wrote the SpringMVC integration and the version of the DispatcherServlet add on to the TJWS Embedded container.

    This does seem like a compelling approach. I’ll try to add on some utilities to make this kind of testing even easier.

    something like
    in your test file

    and in your test:

    @Autowired
    ClientRequestFactory requestFactory;

    @Test
    public void test(){
    SimpleFile file = requestFactory.get(“/filesystem/getFile/content/A”, SimpleFile.class);

    }

    Does that sound good? Do you have any other suggestions?
    }

  2. admin says:

    Solomon, it sounds good. You should support options of unmarshalling (if you want to write a generic purpose utility) for JSON, XML, Atom etc

    I am willing if you need further discussion.

  3. I already added that in the RESTEasy SVN.

    SimpleFile sf = ReaderUtility.read(SimpleFile.class, “application/xml”, responseBodyAsString)

    With a corresponding WriterUtility…

  4. admin says:

    It is good for developers, they do not need to know the raw data is created. Thanks Solomon :)

  5. Srinadh says:

    Hi

    Am using JAXB to marshall and unmarshall both the request and response objects. Its pretty easy and performance is very good compared to SOAP.

  6. admin says:

    Yeah, it is pretty easy to JAXB to marshall and unmarshall java objects. One more option is using JSON serializer/de-serializer, I prefer the second option if it is possible because it is simple, ease of reading and it is ease to make interoperability with other language.

Leave a Reply