Thursday, March 15, 2012

Helloworld web service in Eclipse using Tomcat, Apache CXF and Spring

I have just started working on Spring and was required to expose an existing application as a web service. So to get started I needed to learn about how to create one in Eclipse and deploy it on tomcat. Sadly spending hours and Google and downloading dozens of samples, I was unable to get them work on Eclipse. Most worked using Maven but I wanted to build one in Eclipse from scratch. So lets get started.

Requirements:

To get started:
  1. In Eclipse : Create a New 'Dynamic Web Project'. Name it as 'HelloWS' and click Finish.


  2. Go to Build Path: Configure Build Path.
    1. Under the 'Source' tab: Change the 'Default Output Folder' from 'HelloWS/build/classes' to 'HelloWS/WebContent/WEB-INF/classes'.

    2. Under Libraries tab: Add Spring and Apache CXF libraries.
    3. Under 'Order and Export' tab: Check the chekboxes next to these libraries
    4. Under 'Deployment Assembly' (just above 'Java Build Path' in the 'Properties of HelloWS'  windows) : Click 'Add' :: Java Build Path Entries and select these 2 libraries so that they can be deployed to the Tomcat App Server.
  3. With the configuration done, lets write some code.
  4. Create an interface 'HelloService' under package 'my.service'. Annotate the class with @WebService . Add a simple sayHello method. So it looks like:

    package my.service;

    import javax.jws.WebService;

    @WebService
    public interface HelloService {

        public String sayHello(String name);
       
    }
  5. Next create the implementer class 'HelloServiceImpl' which implements 'HelloService'. Annotate the class with @Webservice and parameter endpointInterface = "my.service.HelloService" which defines the Contract for this Endpoint. So it looks like:

    package my.service;

    import javax.jws.WebService;

    @WebService(endpointInterface = "my.service.HelloService")
    public class HelloServiceImpl implements HelloService {
       
        @Override
        public String sayHello(String name) {
            return "Hello " + name + " !!";
        }
    }
  6. Coding complete. Now lets configure the Spring context which will invoke this service we just created.
  7. Update 'web.xml' under WebContent/WEB-INF folder with the following xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="...">

        <display-name>My Webservice</display-name>

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

        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:my/service/application-context.xml</param-value>
        </context-param>

        <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>/*</url-pattern>
        </servlet-mapping>
      
    </web-app>

    Read this configuration file bottom up. First it instructs all requests matching the URLpattern /* (that is everything to be handled by a servlet named ' CXFServlet' which is defined just above. This is a Apache CXFservlet. Above it we provide the configuration file location which will configure this servlet (details below). Above this, it specifies the Spring Listener class which will listen to all these Http requests.
  8. Now create a 'application-context.xml' file at the same level as the 2 java files coded above with the following xml:

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

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

        <!-- Spring manage ServiceBean -->
        <bean id="myServ" class="my.service.HelloServiceImpl" />

        <!-- JAX-WS Service Endpoint -->
        <jaxws:endpoint id="myService" implementor="#myServ"
            address="/myService" />

    </beans>

    In here, again reading from below, first we define an endpoint named 'myService which is implemented by the bean 'myServ' whose class is 'my.service.HelloServiceImpl' and its binded to the address '/myService'
  9. And we are done with coding.
  10. To deploy it, create a 'Tomcat 7 Server' under Servers in Eclipse and deploy the 'HelloWS' module to it using 'Add and Remove'
  11. Start the server
  12. To check, open your browser and type in : http://localhost:8080/HelloWS and it should open up the default page. You can also get the wsdl at : http://localhost:8080/HelloWS/myService?wsdl
  13. You can use SOAPUI to test your service too.
  14. And in 10 minutes your service is ready :)

5 comments:

DZONEMVB said...

Hi Sandeep,

I'm a community curator at DZone and ran across your blog today while looking for content for our upcoming Enterprise Integration Microzone. I was wondering if you would be interested in having some of your posts republished on our site. If so, please send me an email so I can provide some more information.

Thanks,

Chris Smith
csmith@dzone.com

d-saif said...

Hi Sandeep,
Thanks alot.. The tutorial is very well illustrated and helpful.. I have seen other tutorials, but had gr8 deficulty to configure the cxf.

Thanks again.

Unknown said...

Thank you very much. it very detail.

Unknown said...

Thank you very much. it very detail.

Venu said...

Hi Sandeep,

Thanks much, the blog is much simple and clear.
I have a doubt, is there any chance to create WS with annotations and CXF library and without defining the CXF Servlet/listener in web.xml file?

Thanks, Venu