http://opensourcesoftwareandme.blogspot.hk/2012/12/demystifying-apache-cxf-restful-hello.html

The first post of this how-to series showed you what it takes to expose a Hello World application as a SOAP over HTTP Web Service using CXF. For this post, I'll show you how to expose the same app as a RESTful service.

In the Java world, we use JAX-RS for mapping a class to a RESTful service. Giving a RESTful interface to our Hello World app is just a matter of adding JAX-RS annotations to HelloWorldImpl:

package                     org.opensourcesoftwareandme;                  

                                       

import                     javax.ws.rs.GET;                  

import                     javax.ws.rs.Path;                  

import                     javax.ws.rs.PathParam;                  

import                     javax.ws.rs.Produces;                  

                                       

"/helloWorld")                  

public                     class                     HelloWorldImpl

                                       

@GET

@Produces(                    "text/html")                  

@Path(                    "sayHi/{text}")                  

public                     String                     sayHi(                    @PathParam(                    "text")                     String                     text) {                  

return                     "Hello "                     +

                        }                  

                    }

view raw HelloWorldImpl.java hosted with ❤ by GitHub


In the class, I tell the JAX-RS provider (i.e., CXF):

  • HelloWorldImpl is a resource available on the URL relative path "/helloWorld" (@Path("/helloWorld")).
  • the HTTP reply sent back to the client should have the Content-Type set to "text/hml" (@Produces).
  • sayHi is to be called when the HTTP request is a GET and the relative path is "/helloWorld/sayHi/" + [variable] (@Path("sayHi/{text}")).
  • to bind the URL parameter with the method argument text (@PathParam).

As in the previous how-to, I'm going to deploy the app onto an embedded Jetty server instead of deploying it onto a standalone web container:

package                     org.opensourcesoftwareandme;                  

                                       

import                     org.apache.cxf.jaxrs.JAXRSServerFactoryBean;                  

                                       

import                     javax.ws.rs.ext.RuntimeDelegate;                  

                                       

public                     class                     Server

                                       

public                     static                     void                     main(                    String                     args[])                     throws                     Exception

JAXRSServerFactoryBean jaxrsServerFactory                     =                     RuntimeDelegate                    .getInstance()                    .createEndpoint(                    new                     HelloWorldApp(),                     JAXRSServerFactoryBean                    .class);                  

.setAddress(                    "http://localhost:9000");                  

org.apache.cxf.endpoint.Server server                     = jaxrsServerFactory                    .create();                  

.start();                  

                                       

System                    .out                    .println(                    "Server started...");                  

Thread                    .sleep(                    5                     *                     60                     *                     1000);                  

System                    .out                    .println(                    "Server stopping...");                  

.stop();                  

System                    .exit(                    0);                  

                        }                  

                                       

                    }



view raw Server.java hosted with ❤ by GitHub


RuntimeDelegate.getInstance().createEndpoint(...) is a JAX-RS method that returns an unpublished endpoint. It takes in:

  • a class responsible for configuring and launching the web server. This class differs across JAX-RS providers. CXF expects this class to be JAXRSServerFactoryBean.
  • an object that extends Application. This user-defined class must return JAX-RS annotated classes responsible for processing client requests. For us, this means returning HelloWorldImpl:

package                       org.opensourcesoftwareandme;                    

                                           

import                       javax.ws.rs.core.Application;                    

import                       java.util.Collections;                    

import                       java.util.HashSet;                    

import                       java.util.Set;                    

                                           

public                       class                       HelloWorldApp                       extends                       Application

                                           

public                       Set<Class<?>>                       getClasses() {                    

Set<Class<?>> classes                       =                       new                       HashSet<Class<?>>();                    

.add(                      HelloWorldImpl                      .class);                    

                                           

return

                          }                    

                                           

                      }



view raw HelloWorldApp.java hosted with ❤ by GitHub

Back to our 

Server.java file, I tell the endpoint to bind the server to the URL

http://localhost:9000. Then, from the endpoint, I create a

org.apache.cxf.endpoint.Server object and invoke

start(...) to publish the service. Note that, underneath, 

org.apache.cxf.endpoint.Server is a configured Jetty. 


Before testing the service, I add the required CXF libraries to the Java classpath by declaring them as dependencies in project's POM :

...                   

dependencies>                  

dependency>                  

groupId>org.apache.cxf</                    groupId>                  

artifactId>cxf-rt-frontend-jaxrs</                    artifactId>                  

version>                    ${cxf.version}</                    version>                  

dependency>                  

dependency>                  

groupId>org.apache.cxf</                    groupId>                  

artifactId>cxf-rt-transports-http-jetty</                    artifactId>                  

version>                    ${cxf.version}</                    version>                  

dependency>                  

dependencies>                  

                        ...



view raw pom.xml hosted with ❤ by GitHub


If you compare this POM with the POM of the first how-to, you'll note that now I've swapped the JAX-WS frontend with the JAX-RS one.

All that is left is to run the server with the following Maven commands:

; mvn                     exec:java -Dexec.mainClass=                    "org.opensourcesoftwareandme.Server"



view raw run.sh hosted with ❤ by GitHub

Once the server is up, accessing via your browser the URL http://localhost:9000/helloWorld/sayHi/Ricston