RESTFul Service example using Apache CXF and Spring

In recent times there is lot of growth in RESTFul services. I thought it would be nice to talk about it.

This example is using Apache CXF and Spring. There are some other frameworks e.g Jersey (Reference Sun implementation), RestEasy, the JBoss choice and Apache CXF.

Here is bacic web configuration adding Spring context and CXF tranport servlet.

  <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/services.xml</param-value>
    </context-param>


    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>CXFServlet</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

There is Cities service using Spring annotations, this has been configured using Spring annotation
Second annottatiions is of CXF to define the mount point REST service

@Service("timeService")
@Path("cities")
public class CitiesListingService {

    @GET
    @Produces({"application/json", "application/xml"})
    public RestFulCities getCities() {
        List<City> cities = new LinkedList<City>();
        cities.add(new City("New Delhi", "011", "19M"));
        cities.add(new City("Mumbai", "022", "21M"));
        cities.add(new City("Chennai", "044", "10M"));
        RestFulCities restFulCities = new RestFulCities();
        restFulCities.setRestFulCityList(getCities(cities));
        return restFulCities;
    }

Here is Spring configuration for connection cxf and spring beans together.

<context:component-scan base-package="com.techartifact.example.spring"/>

    <import resource="classpath:META-INF/cxf/cxf.xml"/>
    <import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml"/>
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>

    <jaxrs:server id="restContainer" address="/">
        <jaxrs:serviceBeans>
            <ref bean="timeService"/>
        </jaxrs:serviceBeans>
        <jaxrs:extensionMappings>
            <entry key="json" value="application/json"/>
            <entry key="xml" value="application/xml"/>
        </jaxrs:extensionMappings>
        <jaxrs:providers>
            <ref bean="jaxbXmlProvider"/>
        </jaxrs:providers>
    </jaxrs:server>

    <!-- Webservice message handlers -->
    <bean id="jaxbXmlProvider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
        <property name="jaxbElementClassNames" ref="elements"/>
    </bean>

    <util:list id="elements">
        <value>com.techartifact.example.spring.model.RestFulCity</value>
        <value>com.techartifact.example.spring.model.RestFulCities</value>
    </util:list>

Yes that’s it. Now build the code and run it.

Run example

Download full example code from here spring-RESTapplication

Go to project directory [spring-RESTapplication] in command shell and run following command using maven

mvn clean package
mvn -Pcargo-run

http://localhost:8080/springrest/rest/cities

CXF can also produces output in json format, use following url to see out put in json

http://localhost:8080/springrest/rest/cities.json

SpringMVC example with Maven

Spring MVC is part of Springframework. It allow us to create application based on MVC design pattern in way that, we can leverage other features of Spring like authentication, ORM, AOP and others.

In Spring MVC core component is the DispatcherServlet{link}, It works as front-controller. All request are processed by DispatcherServlet. It is also responbile for deleting request to suitable handlers.

Structure

We are using standard Maven web project structure
spring-mvc-example-project-structure

Dependencies

        <!-- for compile only, your container will provide this  -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
        <!-- Spring-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>3.0.0.RELEASE</version>
        </dependency>
        <!-- JSTL -->
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>

Request Controller

You can use or extend any of controller that comes from Spring or create you own by extendng AbstractController and implement handleRequestInternal method.

package com.techartifact.example.springmvc.controller;


import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloController extends AbstractController {

    private String message;

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        ModelAndView modelAndView = new ModelAndView("hello");
        modelAndView.addObject("message", message);
        return modelAndView;
    }
}

Flow in a Spring MVC application is as follows:

The request is received by our DispatcherServlet

  1. DispatcherServlet has responsibility to find the controller for request. This process would be done in HandlerMapping phase.
  2. After controller has been found, DispatcherServlet will forward the request to Controller.
  3. Controller has the business logic to compute what model it will return to Dispatcher. It means Controller will return Model and view where it needs to displayed
  4. Once the ModelAndView has been dispatched to the DispatcherServlet from controller, DispatcherServlet will asociate the view name sent by the Controller with the specified view.
  5. After the view had been resolved, our DispatcherServlet will pass our Model object to the concrete View.

View

In this example we are using jsp for view

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>SpringMVC Hello world</title>
</head>
<body>
Message from Spring "${message}"
</html>

Spring Configuration

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean name="/hello.htm" class="com.techartifact.example.springmvc.controller.HelloController">
        <property name="message" value="This is sample message"/>
    </bean>

    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/jsp/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>
</beans>

 Web descriptor

<?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_2_5.xsd"
         version="2.5">

    <display-name>Spring MVC example</display-name>

    <servlet>
        <servlet-name>springapp</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>WEB-INF/spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>springapp</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

</web-app>

Run example

Download full example code from here spring-webmvc-example

Go to project directory [spring-webmvc-example] in command shell and run following command using maven

mvn clean package
mvn -Pcargo-run

You should see following output in your browser

http://localhost:8080/springmvc/hello.htm

Using Collections.copy for list

Using java Collections to copy array list

I have seen lot’s of people using Collections.copy and most of times you see this error on console

Exception in thread "main" java.lang.IndexOutOfBoundsException:
Source does not fit in dest.

Normally we use following code to copy an array-list

ArrayList<String> items = new ArrayList<String>();

items.add("item 1");
items.add("item 2");
items.add("item 6");

ArrayList<String> items2= new ArrayList<String>(items.size());
Collections.copy(items2,items);

Only problem in the above code is that for list items2 we are assuming that it has same capacity as list items. If you see the code carefully, it is only setting up initial capacity not size and Collections api check for size instead of capacity of list and it result to exception.

IMO there should be an improvement in collection api to copy items, based on capacity, instead of size. See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6350752 .

Solution

You can use any of following option to copy a list

ArrayList<String> items2= new ArrayList<String>(items);
ArrayList<String> items2 = (ArrayList<String>)items.clone();

References

http://java.sun.com/javase/6/docs/api/java/util/Collections.html#copy(java.util.List,%20java.util.List)
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6350752