Tuesday, October 19, 2010

Exposing the Server Code of your Web application as REST Services using Jersey

I am sure you might have scenarios where you have written a Web Application and modeled your server components as POJO based service methods. You would have a controller layer (Struts/Stripes/Spring MVC/Servlet) to take care of rendering your Web pages as well as responding to AJAX calls.

Now comes the need for developing a Mobile app for your application. Invariably the first and the most common thought would be to expose the POJO methods as REST Services on the Web and access them from the device. JAX-RS (Jersey JSR311) is a great means of very easily converting your POJO methods to REST Services. One another option is to use the controller layer to expose the REST services (Possible with most of the web frameworks), but I am dealing specifically with Jersey on this blog

So assuming you are going to use a Tomcat based deployment, the following are the steps you would perform.

1) Add Jersey JAR files to your WEB-INF/lib
2) Add a servlet mapping for the Jersey's Servlet Container as shown below

    <servlet>
        <servlet-name>JerseyServlet</servlet-name>
        <servlet-class>
            com.sun.jersey.spi.container.servlet.ServletContainer
        </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
           <servlet-name>JerseyServlet</servlet-name>
           <url-pattern>/*</url-pattern>
    </servlet-mapping>

3) Annotate your POJO with the @Path and @GET/@POST etc annotations - A sample can be seen in Sun's site

Trouble starts now

ALL is Well till you run Jersey alone. The moment I merge this content to my Original Web application and add the web.xml, all my Other Servlet Controllers do not work. Even cannot access static files like index.html or images

On carefully looking at it, the problem is definitely due to the Servlet mapping. Now everything goes through the Jersey Container, due to this mapping

<url-pattern>/*</url-pattern>

OK, now that is simple, just change the mapping to something like this

<url-pattern>/api/*</url-pattern>

Now your Jersey mapping changes to the Sub Context and the following url works http://localhost:8080/RestServiceProject/api/helloworld - assuming that the annotation is defined like this @Path("/helloworld")

Another approach for solving the problem is to have a servlet filter definition for Jersey and that approach is explained here

I have configured Jersey along with my web application with the different servlet path approach and that seems to work good so far.

No comments: