SOAP (JAX-WS) Web Service Tutorial with Apache CXF, eclipse and maven
In the previous tutorial RESTful service with Apache CXF was demonstrated. This tutorial modifies the same one for SOAP based Web Service.
Step 1: You need to bring in the relevant CXF framework JAR files. The transitive dependencies will bring in the other dependent Spring jar files, JAXB jar files, and many other jar files listed in the screenshot below.
The pom.xml file is shown below:
Now, if you right-mouse-click on simpleWeb, and select "Maven --> Update Depencies", you can see all the transitively dependent jar files in the "Java Perspective" as shown below.
As you can see, it transitively brings in Spring and JAXB jars in addition to other relevant jars.
Step 2: Define the SOAP (i.e. JAX-WS) Web Service interface and implementation classes with relevant annotations.
Interface HelloUserWebService.java
Implementation HelloUserWebServiceImpl.java
Step 3: Define the web service endpoint via cxf.xml, which internally uses the Spring framework. Define this undersr/main/resources folder under a package com.mytutorial.webservice.
Step 4: The web.xml file and the User.java files are same as the RESTful Web Service tutorial. You should now have the relevant artifacts as shown below.
Step 5: Deploy the simpleWeb.war to the Tomcat server from within eclipse or from outside eclipse as described in the simple web JEE tutorial.
Step 6: Open a wen browser like google chrome, and type the following URL -> http://localhost:8080/simpleWeb/. This will list the JAX-WS and JAX-RS Web services that are available.
Step 7: You can now open a WSDL (Web Services Description Language) file on the browser with the following URL --> http://localhost:8080/simpleWeb/userservices?wsdl
Step 8: From the above WSDL, you can either create a SOAP UI Client to test the above JAX-WS service, or write a stand-alone client Java class to test it programmatically.
The output will be:
Step 1: You need to bring in the relevant CXF framework JAR files. The transitive dependencies will bring in the other dependent Spring jar files, JAXB jar files, and many other jar files listed in the screenshot below.
The pom.xml file is shown below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
| <project xmlns= "http://maven.apache.org/POM/4.0.0" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" <modelVersion>4.0.0</modelVersion> <groupId>com.mytutorial</groupId> <artifactId>simpleWeb</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>simpleWeb Maven Webapp</name> <url>http: //maven.apache.org</url> <properties> <cxf.version>2.2.3</cxf.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <!-- CXF SOAP Web Service JARS --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>${cxf.version}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>${cxf.version}</version> </dependency> </dependencies> <build> <finalName>simpleWeb</finalName> </build> </project> <span style= "font-family: Times New Roman;" ><span style= "white-space: normal;" > </span></span> |
As you can see, it transitively brings in Spring and JAXB jars in addition to other relevant jars.
Step 2: Define the SOAP (i.e. JAX-WS) Web Service interface and implementation classes with relevant annotations.
Interface HelloUserWebService.java
1
2
3
4
5
6
7
8
9
10
11
| package com.mytutorial.webservice; import javax.jws.WebService; import com.mytutorial.pojo.User; @WebService public interface HelloUserWebService { //parameter that gets passed via the URL User greetUser(String userName); } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| package com.mytutorial.webservice; import javax.jws.WebParam; import javax.jws.WebService; import com.mytutorial.pojo.User; @WebService(endpointInterface = "com.mytutorial.webservice.HelloUserWebService" ) public class HelloUserWebServiceImpl implements HelloUserWebService { public User greetUser(@WebParam(name= "name" ) String userName) { User user = new User(); user.setName(userName); return user; } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| <beans xmlns= "http://www.springframework.org/schema/beans" 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" /> <jaxws:endpoint id= "auth" implementor= "com.mytutorial.webservice.HelloUserWebServiceImpl" address= "/userservices" /> </beans> |
Step 4: The web.xml file and the User.java files are same as the RESTful Web Service tutorial. You should now have the relevant artifacts as shown below.
Step 5: Deploy the simpleWeb.war to the Tomcat server from within eclipse or from outside eclipse as described in the simple web JEE tutorial.
Step 6: Open a wen browser like google chrome, and type the following URL -> http://localhost:8080/simpleWeb/. This will list the JAX-WS and JAX-RS Web services that are available.
Step 7: You can now open a WSDL (Web Services Description Language) file on the browser with the following URL --> http://localhost:8080/simpleWeb/userservices?wsdl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
| <?xml version= '1.0' encoding= 'UTF-8' ?><wsdl:definitions name= "HelloUserWebServiceImplService" targetNamespace= "http://webservice.mytutorial.com/" xmlns:ns1= "http://cxf.apache.org/bindings/xformat" xmlns:soap= "http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns= "http://webservice.mytutorial.com/" xmlns:wsdl= "http://schemas.xmlsoap.org/wsdl/" xmlns:xsd= "http://www.w3.org/2001/XMLSchema" > <wsdl:types> <xs:schema elementFormDefault= "unqualified" targetNamespace= "http://webservice.mytutorial.com/" version= "1.0" xmlns:tns= "http://webservice.mytutorial.com/" xmlns:xs= "http://www.w3.org/2001/XMLSchema" > <xs:element name= "greetUser" type= "tns:greetUser" /> <xs:element name= "greetUserResponse" type= "tns:greetUserResponse" /> <xs:element name= "user" type= "tns:user" /> <xs:complexType name= "greetUser" > <xs:sequence> <xs:element minOccurs= "0" name= "arg0" type= "xs:string" /> </xs:sequence> </xs:complexType> <xs:complexType name= "greetUserResponse" > <xs:sequence> <xs:element minOccurs= "0" name= "return" type= "tns:user" /> </xs:sequence> </xs:complexType> <xs:complexType name= "user" > <xs:sequence> <xs:element minOccurs= "0" name= "name" type= "xs:string" /> </xs:sequence> </xs:complexType> </xs:schema> </wsdl:types> <wsdl:message name= "greetUser" > <wsdl:part element= "tns:greetUser" name= "parameters" > </wsdl:part> </wsdl:message> <wsdl:message name= "greetUserResponse" > <wsdl:part element= "tns:greetUserResponse" name= "parameters" > </wsdl:part> </wsdl:message> <wsdl:portType name= "HelloUserWebService" > <wsdl:operation name= "greetUser" > <wsdl:input message= "tns:greetUser" name= "greetUser" > </wsdl:input> <wsdl:output message= "tns:greetUserResponse" name= "greetUserResponse" > </wsdl:output> </wsdl:operation> </wsdl:portType> <wsdl:binding name= "HelloUserWebServiceImplServiceSoapBinding" type= "tns:HelloUserWebService" > <wsdl:operation name= "greetUser" > <soap:operation soapAction= "" style= "document" /> <wsdl:input name= "greetUser" > <soap:body use= "literal" /> </wsdl:input> <wsdl:output name= "greetUserResponse" > <soap:body use= "literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name= "HelloUserWebServiceImplService" > <wsdl:port binding= "tns:HelloUserWebServiceImplServiceSoapBinding" name= "HelloUserWebServiceImplPort" > </wsdl:port> </wsdl:service> </wsdl:definitions> |
Step 8: From the above WSDL, you can either create a SOAP UI Client to test the above JAX-WS service, or write a stand-alone client Java class to test it programmatically.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| package com.mytutorial.client; import org.apache.cxf.interceptor.LoggingInInterceptor; import org.apache.cxf.interceptor.LoggingOutInterceptor; import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; import com.mytutorial.pojo.User; import com.mytutorial.webservice.HelloUserWebService; public final class SoapClientTest { private SoapClientTest() { } public static void main(String args[]) throws Exception { JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); factory.getInInterceptors().add( new LoggingInInterceptor()); factory.getOutInterceptors().add( new LoggingOutInterceptor()); factory.setServiceClass(HelloUserWebService. class ); //The URL should be externalized to a configuration file HelloUserWebService client = (HelloUserWebService) factory.create(); User user = client.greetUser( "John" ); System. out .println( "Response is: " + user.getName()); } } |
The output will be:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| 15/10/2012 1:10:57 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing org.apache.cxf.bus.spring.BusApplicationContext@9506dc4: display name [org.apache.cxf.bus.spring.BusApplicationContext@9506dc4]; startup date [Mon Oct 15 13:10:57 EST 2012]; root of context hierarchy 15/10/2012 1:10:57 PM org.apache.cxf.bus.spring.BusApplicationContext getConfigResources INFO: No cxf.xml configuration file detected, relying on defaults. 15/10/2012 1:10:57 PM org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory INFO: Bean factory for application context [org.apache.cxf.bus.spring.BusApplicationContext@9506dc4]: org.springframework.beans.factory.support.DefaultListableBeanFactory@62da3a1e 15/10/2012 1:10:57 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@62da3a1e: defining beans [cxf,org.apache.cxf.bus.spring.BusApplicationListener,org.apache.cxf.bus.spring.BusWiringBeanFactoryPostProcessor,org.apache.cxf.bus.spring.Jsr250BeanPostProcessor,org.apache.cxf.bus.spring.BusExtensionPostProcessor,org.apache.cxf.resource.ResourceManager,org.apache.cxf.configuration.Configurer,org.apache.cxf.binding.BindingFactoryManager,org.apache.cxf.transport.DestinationFactoryManager,org.apache.cxf.transport.ConduitInitiatorManager,org.apache.cxf.wsdl.WSDLManager,org.apache.cxf.phase.PhaseManager,org.apache.cxf.workqueue.WorkQueueManager,org.apache.cxf.buslifecycle.BusLifeCycleManager,org.apache.cxf.endpoint.ServerRegistry,org.apache.cxf.endpoint.ServerLifeCycleManager,org.apache.cxf.endpoint.ClientLifeCycleManager,org.apache.cxf.transports.http.QueryHandlerRegistry,org.apache.cxf.endpoint.EndpointResolverRegistry,org.apache.cxf.headers.HeaderManager,org.apache.cxf.catalog.OASISCatalogManager,org.apache.cxf.endpoint.ServiceContractResolverRegistry,org.apache.cxf.jaxws.context.WebServiceContextResourceResolver,org.apache.cxf.jaxws.context.WebServiceContextImpl,org.apache.cxf.binding.soap.SoapBindingFactory,org.apache.cxf.binding.soap.SoapTransportFactory,org.apache.cxf.binding.soap.customEditorConfigurer,org.apache.cxf.binding.xml.XMLBindingFactory,org.apache.cxf.ws.addressing.policy.AddressingAssertionBuilder,org.apache.cxf.ws.addressing.policy.AddressingPolicyInterceptorProvider,org.apache.cxf.ws.addressing.policy.UsingAddressingAssertionBuilder,org.apache.cxf.transport.http.policy.HTTPClientAssertionBuilder,org.apache.cxf.transport.http.policy.HTTPServerAssertionBuilder,org.apache.cxf.transport.http.policy.NoOpPolicyInterceptorProvider,org.apache.cxf.transport.http.ClientOnlyHTTPTransportFactory]; root of factory hierarchy 15/10/2012 1:10:58 PM org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromClass INFO: Creating Service {http: //webservice.mytutorial.com/}HelloUserWebServiceService from class com.mytutorial.webservice.HelloUserWebService 15/10/2012 1:10:58 PM org.apache.cxf.interceptor.LoggingOutInterceptor$LoggingCallback onClose INFO: Outbound Message --------------------------- ID: 1 Address: http: //localhost:8080/simpleWeb/userservices Encoding: UTF-8 Content-Type: text/xml Headers: {SOAPAction=[ "" ], Accept=[*/*]} Payload: <soap:envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" ><soap:body><ns2:greetuser xmlns:ns2= "http://webservice.mytutorial.com/" ><arg0>John</arg0></ns2:greetuser></soap:body></soap:envelope> -------------------------------------- 15/10/2012 1:10:59 PM org.apache.cxf.interceptor.LoggingInInterceptor logging INFO: Inbound Message ---------------------------- ID: 1 Encoding: UTF-8 Content-Type: text/xml;charset=UTF-8 Headers: {content-type=[text/xml;charset=UTF-8], Date=[Mon, 15 Oct 2012 02:10:59 GMT], Content-Length=[236], Server=[Apache-Coyote/1.1]} Payload: <soap:envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" ><soap:body><ns2:greetuserresponse xmlns:ns2= "http://webservice.mytutorial.com/" >< return ><name>John</name></ return ></ns2:greetuserresponse></soap:body></soap:envelope> -------------------------------------- Response is : John |
Comments
Post a Comment