Building your own web service

Version 4

    This document contains more specific information on how to create a RESTful Web Service through a plugin. For a sample plugin of this type, including source, please see the attached file.

     

     

    Getting Started

     

    Before we dive in, there are two points to cover. First and foremost, you should make sure the service you need isn't already provided by the existing web services or functionality elsewhere in the application (Jive Support is a good contact to check if you're unsure). Secondly, this document assumes you're already familiar with our Building Plugins and have set up your development environment (our recommended tool to use is Maven: Start Here). With those two things in mind, and assuming you've set up a basic plugin, let's dive in.

     

    Registering your service with Spring

     

    In order for the application to detect your new web service, you must register it as a web service endpoint using JAX-WS. The simplest way to accomplish this is via your plugin's spring.xml file:

     

    Include the JAX-WS schema

     

    First, you'll need to include the jaxws schema for this to work, so at the top of the spring file (as part of the beans element) add the attribute

     

    xmlns:jaxws="http://cxf.apache.org/jaxws"
    

     

    and then add the following to the xsi:schemaLocation attribute :

     

    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
    

     

    Now your beans element should look similar to this:

     

    
    <beans xmlns="http://www.springframework.org/schema/beans"
    
    
           xmlns:jaxws="http://cxf.apache.org/jaxws"
           xsi:schemaLocation="
           default-autowire="no" default-init-method="init" default-destroy-method="destroy">

     

    and you're ready to start registering your web services.

     

    Register an endpoint

     

    You can register a JAX-WS endpoint with the following XML:

     

        <bean id="echoServiceImpl" class="com.jivesoftware.example.webservices.EchoServiceImpl" />     <jaxws:endpoint id="echoRestService"                     address="/rest/echoService"                     bindingUri="http://apache.org/cxf/binding/http">         <jaxws:implementor>             <ref bean="echoServiceImpl" />         </jaxws:implementor>         <jaxws:serviceFactory>             <ref bean="wrappedServiceFactory" />         </jaxws:serviceFactory>     </jaxws:endpoint>
    

     

    What the first line does is create a new spring bean for your web services' implementation, here called EchoServiceImpl. You'll need this bean to register as the web service implementor later on.

     

    The next lines perform the actual registration:

    • The id should uniquely identify your service.
    • The address specifies how users will access your service. The application is pre-configured to for web services to live at http://<application>/<context>/rpc, so this address will define the rest of the URL. Here, we specify that the echo service should be available at http://<application>/<context>/rpc/rest/echoService/<method address> .
    • The bindingUri should be as defined above.
    • The implementor should be a reference to whatever bean implements your webservice.
    • The service factory should remain a wrappedServiceFactory.

     

    Writing the Java code

    Now the hard part: Getting your web service to do something useful. We recommend splitting up your web service across an interface that defines your methods and an implementing class that provides the actual code.

     

    Defining a simple method

     

    You'll need to declare the interface as a web service. To do this, you'll want to use the following annotation (from the javax.jws package):

     

    @WebService(portName = "EchoServicePort", serviceName = "EchoService",         targetNamespace = "http://jivesoftware.com/clearspace/webservices") public interface EchoService {
    

     

    • portName and serviceName should again be unique to your web service
    • targetNamespace should be as above

     

    Then, to declare a method accessible via the web service, you can use (with some annotations in the org.codehaus.jra package):

     

        @WebMethod     @Get     @HttpResource(location = "/hello")     String getHello();
    

     

    This defines a WebMethod that responds to GET requests at the location /hello (so, given our endpoint definition above, this method will respond to requests sent to http://<application>/<context>/rpc/rest/echoService/hello.

     

    Defining a method with parameters

     

    To define a method that takes parameters via the request body, simply use the @WebParam annotation:

     

     

        @WebMethod
        @Post
        @HttpResource(location = "/echo")
        String doEcho(@WebParam(name = "echo")String echo);
    

     

     

    Then, if a POST request is sent to http://<application>/<context>/rpc/rest/echoService/echo with body

     

     

     

     

    <doEcho>
         <echo>
    
              Hello, World!
    
         </echo>
    
    </doEcho>
    

     

     

     

    the echo argument to the doEcho method will be set to "Hello, World!". You can use other types of parameters, such as with this method from the user service:

     

        @WebMethod     @Get     @HttpResource(location = "/properties/{userID}")     List<WSProperty> getUserProperties(@WebParam(name = "userID")long userID) throws UserNotFoundException;
    

     

    which will take an argument of type long. We can also see an example of using the URI itself to pass parameters here, too.

    Implementing the interface

     

    If you've fully defined your methods in the interface (i.e. used the ) then implementing the interface should be almost pure Java, the only Web Service vodoo required is @WebMethod annotation on the methods. After that, everything else should be just like writing a normal plugin.

     

    References