Monday, October 7, 2013

REST Service on JBoss 7 (using CXF) - Part 4

In the last three posts we have been seeing how to host a RESTful service on JBoss 7 by defaulting to the container implementation of JAX-RS, i.e., RESTEasy. However you can use any other implementation with JBoss 7. In fact JBoss 7 itself uses RESTEasy as JAX-RS (RESTful service) implementation and CXF as JAX-WS (SOAP service) implementation.

But what you will miss if you use other implementations such as CXF or other containers such as Spring, is the container management/injection. That is, you can inject any resource such as CDI bean, EJB, Persistence context, transaction, etc into our LibraryService (using annotation/xml configuration) that we saw in the last post. Where as you need to lookup them manually if you use CXF or use any other dependency injection provider such as Spring. Generally it is less hassle to leave it to the app server to manage these resources; but if you dont have a choice (when other teams are using different library or the feature you need is not supported by the app server's default implementation) here you go.

In this article, we will see how to use CXF (without Spring) with JBoss 7. Let's use the same example from the previous post.

1. Create a WEB-INF/web.xml file and replace its content with the below.
<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    <servlet>
        <display-name>CXFNonSpringJaxrsServlet</display-name>
        <servlet-name>CXFNonSpringJaxrsServlet</servlet-name>
        <servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet
        </servlet-class>
        <init-param>
            <param-name>jaxrs.serviceClasses</param-name>
            <param-value>org.jbosstest.jbosstest.LibraryService</param-value>
        </init-param>
        <init-param>
            <param-name>jaxrs.address</param-name>
            <param-value>/</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>CXFNonSpringJaxrsServlet</servlet-name>
        <url-pattern>/webresources/*</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
</web-app>

2. Now add maven dependency for CXF in your pom file as follows.
   <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-bundle-jaxrs</artifactId>
        <version>2.7.5</version>
   </dependency>

3. Exclude the server's default implementation in jboss-deployment-structure.xml file as follows.
<?xml version="1.0" encoding="UTF-8"?>

<jboss-deployment-structure  xmlns="urn:jboss:deployment-structure:1.2">
    <deployment>
        <exclude-subsystems>
            <subsystem name="webservices"/>
            <subsystem name="jaxrs"/>
        </exclude-subsystems>
        <exclusions>
            <module name="javax.ws.rs.api"/>
        </exclusions>
        <!--<exclusions>
        <module name="org.jboss.resteasy.resteasy-jackson-provider"/>
        </exclusions>-->
        <dependencies>
            <!--<module name="org.jboss.resteasy.resteasy-jaxb-provider" services="import"/>
            <module name="org.jboss.resteasy.resteasy-jettison-provider" services="import"/>-->
            <module name="org.codehaus.jettison"/>
        </dependencies>
    </deployment>
</jboss-deployment-structure>

4. You dont need ApplicationConfig.java class any more as you see we have started registering our service classes in web.xml file explicitly.
   <init-param>
        <param-name>jaxrs.serviceClasses</param-name>
        <param-value>org.jbosstest.jbosstest.LibraryService</param-value>
   </init-param>

This is another major difference. You dont have to register the REST service classes anywhere if you use RESTEasy; but you need to list them all in web.xml file if you use any other implementation.

You are done. Use poster as in previous post. Here you go.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bookResponse>
    <books>
        <book>
            <author>Herbert Schildt</author>
            <name>Java The Complete Reference, 8th Edition</name>
            <price>479.0</price>
        </book>
        <book>
            <author>Francesco Marchioni</author>
            <name>Jboss As 7 Configuration, Deployment, And Administration</name>
            <price>450.0</price>
        </book>
        <book>
            <author>Bill Burke</author>
            <name>RESTful Java with JAX-RS 2.0 2ed</name>
            <price>2018.0</price>
        </book>
    </books>
</bookResponse>