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
getting 404 error
LikeLike
you may be missing some libraries. please check.
LikeLike
Pingback: Develop a simple RESTful Webservices using Apache CXF and Spring Framework – Part II | iDoDevJobs
Pingback: Develop a simple RESTful Webservices using Apache CXF and Spring Framework – Part III (Exception/Error handling using ExceptionMapper) | iDoDevJobs
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)
LikeLike
please make sure you have all the required dependencies.
LikeLike
Pingback: Develop a simple RESTful Webservices using Apache CXF and Spring Framework – Part II (Testing using RestTemplate and JUNIT) | iDoDevJobs
Pingback: Develop a simple RESTful Webservices using Apache CXF and Spring Framework – Part III (Exception/Error handling using ExceptionMapper) | iDoDevJobs
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;
LikeLike
you seem to be having issues with the spring version. can you confirm you are using spring 4.0.0?
LikeLike
Pingback: Develop a simple RESTful Webservices using Apache CXF and Spring Framework – Part IV (JAX-RS’ BeanParam Example) | iDoDevJobs
Very helpful. Thank you!
LikeLike
Thanks for this useful post, works for me. thanks again
LikeLiked by 1 person
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?
LikeLike
U have to specify the bean in the web.xml..please find my sprint-ws-context.xml
<!–
–>
<!– –>
<!–
–>
<!– –>
LikeLike
<!–
–>
<!– –>
<!–
–>
<!– –>
LikeLike
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
LikeLike
Pingback: Spring Data REST Java Configuration Example | iDoDevJobs
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.
LikeLike
I followed all the instructions but still getting 404
LikeLike