Develop a simple RESTful Webservices using Apache CXF and Spring Framework – Part I

This article shows how to create a simple RESTful webservices using Apache CXF which supports JAX-RS.

Part I – A simple RESTful Webservices using Apache CXF
Part II – Testing using RestTemplate and JUNIT
Part III – Exception/Error handling using ExceptionMapper
Part IV – BeanParam Example

Apache CXF supports JAX-WS and JAX-RS APIs. It also provides seamless integration with Spring framework.

Service Definition Interface (ExampleService.java)


package com.idodevjobs.sample.service;

import com.idodevjobs.sample.model.ExampleModel;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

@Path("/example")
@Produces("application/json")
public interface ExampleService {

    @GET
    @Path("/{id}")
    public ExampleModel get(@PathParam("id") String id);

}

Service Implementation (ExampleServiceImpl.java)


package com.idodevjobs.sample.service;

import com.idodevjobs.sample.model.ExampleModel;
import org.springframework.stereotype.Service;

@Service("exampleService")
public class ExampleServiceImpl implements ExampleService {

    @Override
    public ExampleModel get(String modelId) {
        return new ExampleModel("example", 1001);
    }
}

Model Object(ExampleModel.java)


package com.idodevjobs.sample.model;

public class ExampleModel {
    private String string;
    private int anInt;

    public ExampleModel() {}

    public ExampleModel(String string, int anInt) {
        this.string = string;
        this.anInt = anInt;
    }

    public String getString() {
        return string;
    }

    public void setString(String string) {
        this.string = string;
    }

    public int getAnInt() {
        return anInt;
    }

    public void setAnInt(int anInt) {
        this.anInt = anInt;
    }

    @Override
    public String toString() {
        return "ExampleModel{" +
                "string='" + string + '\'' +
                ", anInt=" + anInt +
                '}';
    }
}

Web application configuration(web.xml)


<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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">

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring-cxf-rest-example.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>/services/*</url-pattern>
    </servlet-mapping>

</web-app>

Spring/CXF Configuration(spring-cxf-rest-example.xml)


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jaxrs="http://cxf.apache.org/jaxrs"
       xmlns:cxf="http://cxf.apache.org/core"
       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
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                        http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
                        http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">

    <context:component-scan base-package="com.idodevjobs" />

    <jaxrs:server id="exampleCxfServer" address="/">
        <jaxrs:serviceBeans>
            <ref bean="exampleService"/>
        </jaxrs:serviceBeans>
        <jaxrs:extensionMappings>
            <entry key="json" value="application/json"/>
        </jaxrs:extensionMappings>
        <jaxrs:features>
            <cxf:logging/>
        </jaxrs:features>
        <jaxrs:providers>
            <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" />
        </jaxrs:providers>
    </jaxrs:server>

</beans>

Maven Dependency XML(pom.xml)


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>spring-cxf-rest-example</groupId>
    <artifactId>spring-cxf-rest-example</artifactId>
    <packaging>war</packaging>

    <version>1.0-SNAPSHOT</version>
    <name>spring-cxf-rest-example</name>

    <properties>
        <spring.version>4.0.0.RELEASE</spring.version>
        <cxf.version>3.0.0</cxf.version>
        <jackson.version>2.0.1</jackson.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.jaxrs</groupId>
            <artifactId>jackson-jaxrs-json-provider</artifactId>
            <version>${jackson.version}</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>spring-cxf-rest-example</finalName>
    </build>
</project>

Testing

Do a mvn clean install, copy the war to tomcat/webapps directory and start the server by running startup.sh (non-windows) or startup.bat (windows) file.

Open http://localhost:8080/spring-cxf-rest-example/services/example/1 on a browser or any REST client will give

{"string":"example","anInt":1001}

Leave comment for any queries.

Spring framework related tutorials:

REST Webservices using Apache CXF & Spring framework
Spring Data REST using Java configurations
Spring Data REST using XML configurations
Working with multiple properties files in Spring framework
Spring RestTemplate example
Spring prototype scope example

This entry was posted in java and tagged , , , . Bookmark the permalink.

20 Responses to Develop a simple RESTful Webservices using Apache CXF and Spring Framework – Part I

  1. Anonymous says:

    getting 404 error

    Like

  2. Pingback: Develop a simple RESTful Webservices using Apache CXF and Spring Framework – Part II | iDoDevJobs

  3. Pingback: Develop a simple RESTful Webservices using Apache CXF and Spring Framework – Part III (Exception/Error handling using ExceptionMapper) | iDoDevJobs

  4. I get this error:

    org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named ‘cxf’ is defined
    org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:529)
    org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1095)
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:277)
    org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1097)
    org.apache.cxf.transport.servlet.CXFServlet.loadBus(CXFServlet.java:75)
    org.apache.cxf.transport.servlet.CXFNonSpringServlet.init(CXFNonSpringServlet.java:66)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    java.lang.Thread.run(Thread.java:744)

    Like

  5. Pingback: Develop a simple RESTful Webservices using Apache CXF and Spring Framework – Part II (Testing using RestTemplate and JUNIT) | iDoDevJobs

  6. Pingback: Develop a simple RESTful Webservices using Apache CXF and Spring Framework – Part III (Exception/Error handling using ExceptionMapper) | iDoDevJobs

  7. Muhammed Rahman says:

    Hi,
    I have created all files as per your description and set up the project; It builds successfully; but when I start tomcat server, following error occurs:
    ERROR Context initialization failed
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘exampleCxfServer’: Error setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
    PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property ‘serviceBeans’ threw exception; nested exception is java.lang.NoSuchMethodError: org.springframework.util.ClassUtils.isCglibProxyClass(Ljava/lang/Class;)Z
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1279)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1010)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:380)
    at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:255)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4887)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5381)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633)
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:977)
    at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1655)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)
    Caused by: org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
    PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property ‘serviceBeans’ threw exception; nested exception is java.lang.NoSuchMethodError: org.springframework.util.ClassUtils.isCglibProxyClass(Ljava/lang/Class;)Z
    at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:104)
    at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:59)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1276)
    … 30 more
    Thank you for your time and help;

    Like

  8. Pingback: Develop a simple RESTful Webservices using Apache CXF and Spring Framework – Part IV (JAX-RS’ BeanParam Example) | iDoDevJobs

  9. Thanks for this useful post, works for me. thanks again

    Liked by 1 person

  10. David Gibson says:

    Hi

    Good example. I got this deployed on tomcat 7 but when I hit the URL I get:
    No service was found.
    Also I see in the server console :

    2015-09-02 15:38:40 WARN ServletController:156 – Can’t find the the request for http://localhost:8080/CxfRestService_2/services/example/1's Observer

    You sure the URL is correct?

    Like

  11. Anonymous says:

    Hi

    Good example. I got this deployed on Jboss 5.1 but when I hit the URL I get:
    No service was found.
    Also I see in the server console :

    WARNING [ServletController] Can’t find the the request for http://localhost:8080/EquineService/services/example/1's Observer

    Like

  12. Pingback: Spring Data REST Java Configuration Example | iDoDevJobs

  13. Matrix says:

    Or my god.This worked for me.You saved my life.Anyone don’t take bad mined about this.This is work fine.Thank you.

    Like

  14. Anonymous says:

    I followed all the instructions but still getting 404

    Like

Leave a comment