Creating jax-ws webservice in Mule Project
Consuming jax-ws webservice in Mule Project
Creating JAX-WS Webservice using Maven
SOAP Fault handling using Exception in JAX-WS webservice
Create SOAP Webservice using Apache CXF, Spring, Maven
Consume SOAP Webservice using Apache CXF, Spring, Maven
Contract-first Webservice
Creating JAX-WS Webservice using Maven
This tutorial will show you how we can publish and consume SOAP based JAX-WS webservice using maven wsgen and wsimport plugin. For this tutorial we will create two maven projects – first will be an web project and second one will be a standalone project in Eclipse.
If you already have an idea on how to create a maven project in Eclipse will be great otherwise I will tell you here how to create a maven project in Eclipse.
Prerequisites
The following configurations are required in order to run the application
Eclipse Kepler
JDK 1.7
Tomcat 7
Have maven installed and configured
JAX-WS dependencies in pom.xml
Now we will see the below steps how to create a maven based spring project in Eclipse
First we will create service project
Step 1. Create a maven based web project in Eclipse
Go to File -> New -> Other. On popup window under Maven select Maven Project. Then click on Next. Select the workspace location – either default or browse the location. Click on Next. Now in next window select the row as highlighted from the below list of archtypes and click on Next button.
maven-arctype-webapp
Now enter the required fields (Group Id, Artifact Id) as shown below
Group Id : com.roytuts
Artifact Id : soapservice
Step 2. Modify the pom.xml file as shown below.
<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>com.roytuts</groupId> <artifactId>soapservice</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>soapservice Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <jdk.version>1.7</jdk.version> <jaxws.version>2.1.3</jaxws.version> <junit.version>4.11</junit.version> </properties> <dependencies> <dependency> <groupId>com.sun.xml.ws</groupId> <artifactId>jaxws-rt</artifactId> <version>${jaxws.version}</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>soapservice</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>${jdk.version}</source> <target>${jdk.version}</target> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jaxws-maven-plugin</artifactId> <version>1.12</version> <executions> <execution> <phase>process-classes</phase> <goals> <goal>wsgen</goal> </goals> </execution> </executions> <configuration> <sei>com.roytuts.soap.service.HelloServiceImpl</sei> <genWsdl>true</genWsdl> <keep>true</keep> <resourceDestDir>${basedir}/src/main/webapp/WEB-INF/wsdl</resourceDestDir> <sourceDestDir>${basedir}/src/main/java</sourceDestDir> </configuration> </plugin> </plugins> </build> </project>
Step 3. If you see JRE System Library[J2SE-1.4] then change the version by below process
Do right-click on the project and go to Build -> Configure build path, under Libraries tab click on JRE System Library[J2SE-1.4], click on Edit button and select the appropriate jdk 1.7 from the next window. Click on Finish then Ok.
Step 4. Create below HelloServiceImpl.java
package com.roytuts.soap.service; import javax.jws.WebService; @WebService public class HelloServiceImpl { public String sayHello() { return "Hello"; } }
Step 5. Modify web.xml file as below under WEB-INF folder
<?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_3_0.xsd" version="3.0"> <display-name>SOAP Web Service</display-name> <listener> <listener-class> com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class> </listener> <servlet> <servlet-name>HelloService</servlet-name> <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloService</servlet-name> <url-pattern>/HelloService</url-pattern> </servlet-mapping> </web-app>
Step 6. Create sun-jaxws.xml file with the below content under WEB-INF folder
<?xml version="1.0" encoding="UTF-8"?> <endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0"> <endpoint name="HelloService" implementation="com.roytuts.soap.service.HelloServiceImpl" url-pattern="/HelloService" /> </endpoints>
Step 7. Now navigate to the project location from command prompt and build using maven tool by executing the below command
mvn clean compile install
Step 8. Now run or deploy the project into Tomcat server
Step 9. Hit the below URL and you will see the output in the browser
http://localhost:8080/soapservice/HelloService
Step 10. Click on the below URL to see the WSDL content
http://localhost:8080/soapservice/HelloService?wsdl
Now we will create a client project for consuming the service
Step 1. Create a standalone maven project in Eclipse
Go to File -> New -> Other. On popup window under Maven select Maven Project. Then click on Next. Select the workspace location – either default or browse the location. Click on Next. Now in next window select the row as highlighted from the below list of archtypes and click on Next button.
maven-arctype-quickstart
Now enter the required fields (Group Id, Artifact Id) as shown below
Group Id : com.roytuts
Artifact Id : soapclient
Step 2. Modify the pom.xml file as shown below.
<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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.roytuts</groupId> <artifactId>soapclient</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>soapclient</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <jdk.version>1.7</jdk.version> <junit.version>4.11</junit.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>soapservice</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>${jdk.version}</source> <target>${jdk.version}</target> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jaxws-maven-plugin</artifactId> <version>1.12</version> <executions> <execution> <goals> <goal>wsimport</goal> </goals> <configuration> <wsdlUrls> <wsdlUrl>http://localhost:8080/soapservice/HelloService?wsdl</wsdlUrl> </wsdlUrls> <keep>true</keep> <packageName>com.roytuts.soap.client</packageName> <sourceDestDir>${basedir}/src/main/java</sourceDestDir> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.5</version> <executions> <execution> <id>add-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>${basedir}/src/main/java</source> </sources> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
Step 3. If you see JRE System Library[J2SE-1.4] then change the version by below process
Do right-click on the project and go to Build -> Configure build path, under Libraries tab click on JRE System Library[J2SE-1.4], click on Edit button and select the appropriate jdk 1.8 from the next window. Click on Finish then Ok.
Step 4. Navigate to the project location and build the project using maven based tool by executing the below command in command prompt.
Note that the service project (soapservice) must be up and running.
mvn clean compile install
Step 5. Create a Java main class to test the service
package com.roytuts.soap.client; public class HelloClient { public static void main(String[] args) { HelloServiceImplService helloService = new HelloServiceImplService(); HelloServiceImpl helloServiceImpl = helloService.getHelloServiceImplPort(); String response = helloServiceImpl.sayHello(); System.out.println(response); } }
Step 6. Now run the HelloClient.java and you will get the below output in the console.
Hello
That’s all. Thanks for reading.
The post Creating JAX-WS Webservice using Maven appeared first on JEE Tutorials.
SOAP Fault handling using Exception in JAX-WS webservice
This tutorial will show you how we can generate SOAP fault error code and message using Exception handling in SOAP based JAX-WS webservice. For this tutorial we will create a standalone project in Eclipse.
If you already have an idea on how to create a maven project in Eclipse will be great otherwise I will tell you here how to create a maven project in Eclipse.
Prerequisites
The following configurations are required in order to run the application
Eclipse Kepler
JDK 1.8
Have maven installed and configured
JAX-WS dependencies in pom.xml
Now we will see the below steps how to create a maven based spring project in Eclipse
First we will create service project
Step 1. Create a maven based web project in Eclipse
Go to File -> New -> Other. On popup window under Maven select Maven Project. Then click on Next. Select the workspace location – either default or browse the location. Click on Next. Now in next window select the row as highlighted from the below list of archtypes and click on Next button.
maven-arctype-quickstart
Now enter the required fields (Group Id, Artifact Id) as shown below
Group Id : com.roytuts
Artifact Id : soapws
Step 2. Modify the pom.xml file as shown below.
<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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.roytuts</groupId> <artifactId>soapws</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>soapws</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <jdk.version>1.8</jdk.version> <jaxws.version>2.1.3</jaxws.version> </properties> <dependencies> <dependency> <groupId>com.sun.xml.ws</groupId> <artifactId>jaxws-rt</artifactId> <version>${jaxws.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>${jdk.version}</source> <target>${jdk.version}</target> </configuration> </plugin> <plugin> <!-- for jdk 1.6 start --> <!--<groupId>org.codehaus.mojo</groupId> <artifactId>jaxws-maven-plugin</artifactId> <version>1.12</version> --> <!-- for jdk 1.6 end --> <groupId>org.jvnet.jax-ws-commons</groupId> <artifactId>jaxws-maven-plugin</artifactId> <version>2.2</version> <executions> <execution> <phase>process-classes</phase> <goals> <goal>wsgen</goal> </goals> </execution> </executions> <configuration> <sei>com.roytuts.ws.service.BillDeskBOImpl</sei> <genWsdl>true</genWsdl> <keep>true</keep> <resourceDestDir>${basedir}/src/main/webapp/WEB-INF/wsdl</resourceDestDir> <sourceDestDir>${basedir}/src/main/java</sourceDestDir> </configuration> </plugin> </plugins> </build> </project>
Step 3. If you see JRE System Library[J2SE-1.5] then change the version by below process
Do right-click on the project and go to Build -> Configure build path, under Libraries tab click on JRE System Library[J2SE-1.5], click on Edit button and select the appropriate jdk 1.8 from the next window. Click on Finish then Ok.
Step 4. Create below service endpoint interface BillDeskBO.java
package com.roytuts.ws.service; import javax.jws.WebMethod; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import javax.jws.soap.SOAPBinding.Style; import javax.jws.soap.SOAPBinding.Use; import com.roytuts.ws.exception.FortuneBankException; import com.roytuts.ws.vo.BillDeskVO; @WebService @SOAPBinding(style = Style.DOCUMENT, use = Use.LITERAL) public interface BillDeskBO { @WebMethod public void validateDetails(String userName, String password) throws FortuneBankException; @WebMethod public String payBill(BillDeskVO billdeskVO) throws FortuneBankException; }
Step 5. Create below service implementation class
package com.roytuts.ws.service; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import javax.jws.WebService; import com.roytuts.ws.exception.FortuneBankException; import com.roytuts.ws.exception.ServiceFault; import com.roytuts.ws.vo.BillDeskVO; @WebService(endpointInterface = "com.roytuts.ws.service.BillDeskBO") public class BillDeskBOImpl implements BillDeskBO { @Override public void validateDetails(String userName, String password) throws FortuneBankException { try { if (userName != null && password != null && !("admin".equals(userName.trim()) && "admin".equals(password.trim()))) { ServiceFault fault = new ServiceFault(); fault.setFaultCode("1000"); fault.setFaultString("Username and password are incorrect"); throw new FortuneBankException("1000", "Username and password are incorrect"); } } catch (FortuneBankException e) { ServiceFault fault = new ServiceFault(); fault.setFaultCode("2000"); fault.setFaultString("Unknown error"); throw new FortuneBankException("Unknown error => ", e); } } @Override public String payBill(BillDeskVO billdeskVO) throws FortuneBankException { try { if (billdeskVO != null) { float paymentAmount = billdeskVO.getPaymentAmount(); if (paymentAmount > 1) { final DateFormat df = new SimpleDateFormat("yyMMddHHmmss"); final Date date = new Date(); String formattedDate = df.format(date); String customerID = billdeskVO.getCustomerID(); String transactionId = customerID + formattedDate; return transactionId; } else { ServiceFault fault = new ServiceFault(); fault.setFaultCode("3000"); fault.setFaultString("Payment Amount must be greated than 1 to get a Transaction ID"); throw new FortuneBankException("3000", "Payment Amount must be greated than 1 to get a Transaction ID"); } } else { ServiceFault fault = new ServiceFault(); fault.setFaultCode("4000"); fault.setFaultString("BillDeskVO billdeskVO is null"); throw new FortuneBankException("4000", "BillDeskVO billdeskVO is null"); } } catch (FortuneBankException e) { ServiceFault fault = new ServiceFault(); fault.setFaultCode("2000"); fault.setFaultString("Unknown error"); throw new FortuneBankException("Unknown error => ", e); } } }
Step 6. Create below POJO class
package com.roytuts.ws.vo; public class BillDeskVO { private String customerID; private String password; private Float paymentAmount; public String getCustomerID() { return customerID; } public void setCustomerID(String customerID) { this.customerID = customerID; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Float getPaymentAmount() { return paymentAmount; } public void setPaymentAmount(Float paymentAmount) { this.paymentAmount = paymentAmount; } }
Step 7. Create below class for handling SOAP fault error code and error message
package com.roytuts.ws.exception; public class ServiceFault { private String faultCode; private String faultString; public String getFaultCode() { return faultCode; } public void setFaultCode(String faultCode) { this.faultCode = faultCode; } public String getFaultString() { return faultString; } public void setFaultString(String faultString) { this.faultString = faultString; } }
Step 8. Create below custom Exception class for handling fault error code and error message using Exception
package com.roytuts.ws.exception; public class FortuneBankException extends Exception { private static final long serialVersionUID = 1L; private ServiceFault fault; public FortuneBankException(String message) { super(message); } public FortuneBankException(Throwable throwable) { super(throwable); } public FortuneBankException(String message, Throwable throwable) { super(message, throwable); } public FortuneBankException() { } protected FortuneBankException(ServiceFault fault) { super(fault.getFaultString()); this.fault = fault; } public FortuneBankException(String message, ServiceFault faultInfo) { super(message); this.fault = faultInfo; } public FortuneBankException(String message, ServiceFault faultInfo, Throwable cause) { super(message, cause); this.fault = faultInfo; } public ServiceFault getFaultInfo() { return fault; } public FortuneBankException(String code, String message) { super(message); this.fault = new ServiceFault(); this.fault.setFaultString(message); this.fault.setFaultCode(code); } }
Step 9. Now build the project by executing below command from command prompt. Navigate to the project root directory and execute the below command
<physical drive location>soapws>mvn clean compile install -Dmaven.test.skip
If you see BUILD SUCCESSFUL message after executing above command then refresh the project in Eclipse, you will see below few classes have been generated under the package com.roytuts.ws.service.jaxws
The generated xsd is below under WEB-INF/wsdl
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <xs:schema version="1.0" targetNamespace="http://service.ws.roytuts.com/" xmlns:tns="http://service.ws.roytuts.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="FortuneBankException" type="tns:FortuneBankException"/> <xs:element name="payBill" type="tns:payBill"/> <xs:element name="payBillResponse" type="tns:payBillResponse"/> <xs:element name="validateDetails" type="tns:validateDetails"/> <xs:element name="validateDetailsResponse" type="tns:validateDetailsResponse"/> <xs:complexType name="validateDetails"> <xs:sequence> <xs:element name="arg0" type="xs:string" minOccurs="0"/> <xs:element name="arg1" type="xs:string" minOccurs="0"/> </xs:sequence> </xs:complexType> <xs:complexType name="validateDetailsResponse"> <xs:sequence/> </xs:complexType> <xs:complexType name="FortuneBankException"> <xs:sequence> <xs:element name="faultInfo" type="tns:serviceFault" minOccurs="0"/> <xs:element name="message" type="xs:string" minOccurs="0"/> </xs:sequence> </xs:complexType> <xs:complexType name="serviceFault"> <xs:sequence> <xs:element name="faultCode" type="xs:string" minOccurs="0"/> <xs:element name="faultString" type="xs:string" minOccurs="0"/> </xs:sequence> </xs:complexType> <xs:complexType name="payBill"> <xs:sequence> <xs:element name="arg0" type="tns:billDeskVO" minOccurs="0"/> </xs:sequence> </xs:complexType> <xs:complexType name="billDeskVO"> <xs:sequence> <xs:element name="customerID" type="xs:string" minOccurs="0"/> <xs:element name="password" type="xs:string" minOccurs="0"/> <xs:element name="paymentAmount" type="xs:float" minOccurs="0"/> </xs:sequence> </xs:complexType> <xs:complexType name="payBillResponse"> <xs:sequence> <xs:element name="return" type="xs:string" minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:schema>
The generated wsdl file is below under WEB-INF/wsdl
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.2.6b21 svn-revision#12959. --> <definitions targetNamespace="http://service.ws.roytuts.com/" name="BillDeskBOImplService" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:tns="http://service.ws.roytuts.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata"> <types> <xsd:schema> <xsd:import namespace="http://service.ws.roytuts.com/" schemaLocation="BillDeskBOImplService_schema1.xsd"/> </xsd:schema> </types> <message name="validateDetails"> <part name="parameters" element="tns:validateDetails"/> </message> <message name="validateDetailsResponse"> <part name="parameters" element="tns:validateDetailsResponse"/> </message> <message name="FortuneBankException"> <part name="fault" element="tns:FortuneBankException"/> </message> <message name="payBill"> <part name="parameters" element="tns:payBill"/> </message> <message name="payBillResponse"> <part name="parameters" element="tns:payBillResponse"/> </message> <portType name="BillDeskBO"> <operation name="validateDetails"> <input wsam:Action="http://service.ws.roytuts.com/BillDeskBO/validateDetailsRequest" message="tns:validateDetails"/> <output wsam:Action="http://service.ws.roytuts.com/BillDeskBO/validateDetailsResponse" message="tns:validateDetailsResponse"/> <fault message="tns:FortuneBankException" name="FortuneBankException" wsam:Action="http://service.ws.roytuts.com/BillDeskBO/validateDetails/Fault/FortuneBankException"/> </operation> <operation name="payBill"> <input wsam:Action="http://service.ws.roytuts.com/BillDeskBO/payBillRequest" message="tns:payBill"/> <output wsam:Action="http://service.ws.roytuts.com/BillDeskBO/payBillResponse" message="tns:payBillResponse"/> <fault message="tns:FortuneBankException" name="FortuneBankException" wsam:Action="http://service.ws.roytuts.com/BillDeskBO/payBill/Fault/FortuneBankException"/> </operation> </portType> <binding name="BillDeskBOImplPortBinding" type="tns:BillDeskBO"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <operation name="validateDetails"> <soap:operation soapAction=""/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> <fault name="FortuneBankException"> <soap:fault name="FortuneBankException" use="literal"/> </fault> </operation> <operation name="payBill"> <soap:operation soapAction=""/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> <fault name="FortuneBankException"> <soap:fault name="FortuneBankException" use="literal"/> </fault> </operation> </binding> <service name="BillDeskBOImplService"> <port name="BillDeskBOImplPort" binding="tns:BillDeskBOImplPortBinding"> <soap:address location="REPLACE_WITH_ACTUAL_URL"/> </port> </service> </definitions>
Step 10. Create a webservice publisher class which will publish the webservice
package com.roytuts.ws.publisher; import javax.xml.ws.Endpoint; import com.roytuts.ws.service.BillDeskBOImpl; public class BillDeskPublisher { public static void main(String[] args) { Endpoint.publish("http://localhost:8888/soap/billdesk", new BillDeskBOImpl()); } }
Step 11. Create below client class to consume the service
package com.roytuts.ws.client; import java.net.URL; import javax.xml.namespace.QName; import javax.xml.ws.Service; import com.roytuts.ws.service.BillDeskBO; import com.roytuts.ws.vo.BillDeskVO; public class BillDeskClient { public static void main(String[] args) throws Exception { URL url = new URL("http://localhost:8888/soap/billdesk?wsdl"); QName qname = new QName("http://service.ws.roytuts.com/", "BillDeskBOImplService"); Service service = Service.create(url, qname); BillDeskBO billDesk = service.getPort(BillDeskBO.class); billDesk.validateDetails("admin", ""); BillDeskVO billdeskVO = new BillDeskVO(); billdeskVO.setCustomerID("1000"); billdeskVO.setPassword("admin"); billdeskVO.setPaymentAmount(4500214f); System.out.println(billDesk.payBill(billdeskVO)); } }
Step 12. Now run first publisher class then run client class, you will see below output
Nov 29, 2015 11:52:04 AM com.sun.xml.ws.server.sei.EndpointMethodHandler invoke INFO: Unknown error => com.roytuts.ws.exception.FortuneBankException: Unknown error => at com.roytuts.ws.service.BillDeskBOImpl.validateDetails(BillDeskBOImpl.java:30) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at com.sun.xml.ws.api.server.InstanceResolver$1.invoke(InstanceResolver.java:246) at com.sun.xml.ws.server.InvokerTube$2.invoke(InvokerTube.java:146) at com.sun.xml.ws.server.sei.EndpointMethodHandler.invoke(EndpointMethodHandler.java:257) at com.sun.xml.ws.server.sei.SEIInvokerTube.processRequest(SEIInvokerTube.java:93) at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:595) at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:554) at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:539) at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:436) at com.sun.xml.ws.server.WSEndpointImpl$2.process(WSEndpointImpl.java:243) at com.sun.xml.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:444) at com.sun.xml.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:244) at com.sun.xml.ws.transport.http.server.WSHttpHandler.handleExchange(WSHttpHandler.java:106) at com.sun.xml.ws.transport.http.server.WSHttpHandler.handle(WSHttpHandler.java:91) at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79) at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:83) at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:82) at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:675) at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79) at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:647) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: com.roytuts.ws.exception.FortuneBankException: Username and password are incorrect at com.roytuts.ws.service.BillDeskBOImpl.validateDetails(BillDeskBOImpl.java:24) ... 26 more
Now replace
billDesk.validateDetails("admin", "");
by
billDesk.validateDetails("admin", "admin");
you will get similar output like below
1000151129115342
Thanks for reading.
The post SOAP Fault handling using Exception in JAX-WS webservice appeared first on JEE Tutorials.
Create SOAP Webservice using Apache CXF, Spring, Maven
This tutorial will show you how we can publish SOAP based webservice using Apache cxf, Spring and Maven. For this tutorial we will create one maven web project in Eclipse. Please read also https://www.jeejava.com/consume-soap-webservice-using-apache-cxf-spring-maven/
If you already have an idea on how to create a maven project in Eclipse will be great otherwise I will tell you here how to create a maven project in Eclipse.
Prerequisites
The following configurations are required in order to run the application
Eclipse Kepler
JDK 1.8(if you use jdk 1.7 then use Tomcat 7)
Tomcat 8
Have maven installed and configured
Apache cxf and Spring dependencies in pom.xml
Now we will see the below steps how to create a maven based spring project in Eclipse
First we will create service project
Step 1. Create a maven based web project in Eclipse
Go to File -> New -> Other. On popup window under Maven select Maven Project. Then click on Next. Select the workspace location – either default or browse the location. Click on Next. Now in next window select the row as highlighted from the below list of archtypes and click on Next button.
maven-arctype-webapp
Now enter the required fields (Group Id, Artifact Id) as shown below
Group Id : com.roytuts
Artifact Id : cxf-spring
Step 2. Modify the pom.xml file as shown below.
<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>com.roytuts</groupId> <artifactId>cxf-spring</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>cxf-spring Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <jdk.version>1.8</jdk.version> <cxf.version>3.0.4</cxf.version> <spring.version>4.0.5.RELEASE</spring.version> </properties> <dependencies> <!-- Spring dependencies --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <!-- Apache cxf dependencies --> <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> <!-- servlet & jsp --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.1.2</version> </dependency> </dependencies> <build> <finalName>${project.artifactId}</finalName> <plugins> <!-- maven compiler plugin definition --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.2</version> <configuration> <source>${jdk.version}</source> <target>${jdk.version}</target> </configuration> </plugin> <!-- apache cxf plugin for generating wsdl --> <plugin> <groupId>org.apache.cxf</groupId> <artifactId>cxf-java2ws-plugin</artifactId> <version>${cxf.version}</version> <executions> <execution> <id>process-classes</id> <phase>process-classes</phase> <configuration> <!-- service endpoint interface or class --> <className>com.roytuts.service.ProductService</className> <!-- location where wsdl file will be generated --> <outputFile>${project.basedir}/src/main/resources/wsdl/ProductService.wsdl</outputFile> <genWsdl>true</genWsdl> <verbose>true</verbose> <!-- mention service address otherwise it will generate default URL --> <!-- pattern : http://<host>:<port>/<project artifactId will be used as context-path here or you may have different context path>/<service end point> --> <address>http://localhost:8080/${project.artifactId}/services/productService</address> </configuration> <goals> <goal>java2ws</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
Step 3. If you see JRE System Library[J2SE-1.5] then change the version by below process
Do right-click on the project and go to Build -> Configure build path, under Libraries tab click on JRE System Library[J2SE-1.5], click on Edit button and select the appropriate jdk 1.8 from the next window. Click on Finish then Ok.
Step 4. Create service endpoint interface in package com.roytuts.service
package com.roytuts.service; import java.util.List; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebService; import com.roytuts.model.Product; @WebService public interface ProductService { @WebMethod public Product getProduct(@WebParam(name = "productId") int productId); @WebMethod public List<Product> getAllProducts(); }
Step 5. Create service endpoint implementation class
package com.roytuts.service.impl; import java.util.List; import javax.jws.WebService; import com.roytuts.mock.ProductServiceMockDaoImpl; import com.roytuts.model.Product; import com.roytuts.service.ProductService; //mention endpoint interface and serviceName @WebService(endpointInterface = "com.roytuts.service.ProductService", serviceName = "productService") public class ProductServiceImpl implements ProductService { private ProductServiceMockDaoImpl productServiceMockImpl; public void setProductServiceMockImpl(ProductServiceMockDaoImpl productServiceMockImpl) { this.productServiceMockImpl = productServiceMockImpl; } @Override public Product getProduct(int productId) { return productServiceMockImpl.getProduct(productId); } @Override public List<Product> getAllProducts() { return productServiceMockImpl.getAllProducts(); } }
Step 6. Create model class Product
package com.roytuts.model; import java.io.Serializable; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "Product") public class Product implements Serializable { private static final long serialVersionUID = 1L; private int productId; private String productName; private String productCatg; public Product() { } public Product(int productId, String productName, String productCatg) { this.productId = productId; this.productName = productName; this.productCatg = productCatg; } public int getProductId() { return productId; } public void setProductId(int productId) { this.productId = productId; } public String getProductName() { return productName; } public void setProductName(String productName) { this.productName = productName; } public String getProductCatg() { return productCatg; } public void setProductCatg(String productCatg) { this.productCatg = productCatg; } }
Step 7. Create mock data class because we are not using database to store data
package com.roytuts.mock; import java.util.ArrayList; import java.util.List; import com.roytuts.model.Product; public class ProductServiceMockDaoImpl { List<Product> productList = new ArrayList<Product>(); public ProductServiceMockDaoImpl() { Product p1 = new Product(101, "Laptop", "Electronics"); Product p2 = new Product(102, "Bannana", "Fruits"); Product p3 = new Product(103, "Pencil", "Stationary"); productList.add(p1); productList.add(p2); productList.add(p3); } public Product getProduct(int id) { for (Product product : productList) { if (product.getProductId() == id) { return product; } } return null; } public List<Product> getAllProducts() { return productList; } }
Step 8. Create Spring XML configuration file called spring-beans.xml and put it under src/main/resources folder
<?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" /> <bean id="mockDataLayer" class="com.roytuts.mock.ProductServiceMockDaoImpl" /> <bean id="productServiceImpl" class="com.roytuts.service.impl.ProductServiceImpl"> <property name="productServiceMockImpl"> <ref bean="mockDataLayer" /> </property> </bean> <jaxws:endpoint id="productService" implementor="#productServiceImpl" address="/productService" /> </beans>
Step 9. Modify web.xml file as shown below
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>Product Service Web Service</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-beans.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <description>CXF Servlet</description> <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>
Step 10. Now run “mvn clean compile install” command from command prompt on project directory “cxf-spring”. You will see that wsdl file is generated into the location “src/main/resources/wsdl/ProductService.wsdl”
Step 11. Now deploy the project into Tomcat 8 server from Eclipse. You can also access the wsdl file from the location “http://localhost:8080/cxf-spring/services/productService?wsdl”
The generated ProductService.wsdl looks like below under src/main/resources/wsdl folder
<?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions name="ProductServiceService" targetNamespace="http://service.roytuts.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://service.roytuts.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> <wsdl:types> <xs:schema xmlns:tns="http://service.roytuts.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified" targetNamespace="http://service.roytuts.com/" version="1.0"> <xs:element name="Product" type="tns:product"/> <xs:element name="getAllProducts" type="tns:getAllProducts"/> <xs:element name="getAllProductsResponse" type="tns:getAllProductsResponse"/> <xs:element name="getProduct" type="tns:getProduct"/> <xs:element name="getProductResponse" type="tns:getProductResponse"/> <xs:complexType name="getProduct"> <xs:sequence> <xs:element name="productId" type="xs:int"/> </xs:sequence> </xs:complexType> <xs:complexType name="getProductResponse"> <xs:sequence> <xs:element minOccurs="0" name="return" type="tns:product"/> </xs:sequence> </xs:complexType> <xs:complexType name="product"> <xs:sequence> <xs:element minOccurs="0" name="productCatg" type="xs:string"/> <xs:element name="productId" type="xs:int"/> <xs:element minOccurs="0" name="productName" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:complexType name="getAllProducts"> <xs:sequence/> </xs:complexType> <xs:complexType name="getAllProductsResponse"> <xs:sequence> <xs:element maxOccurs="unbounded" minOccurs="0" name="return" type="tns:product"/> </xs:sequence> </xs:complexType> </xs:schema> </wsdl:types> <wsdl:message name="getAllProductsResponse"> <wsdl:part name="parameters" element="tns:getAllProductsResponse"> </wsdl:part> </wsdl:message> <wsdl:message name="getProduct"> <wsdl:part name="parameters" element="tns:getProduct"> </wsdl:part> </wsdl:message> <wsdl:message name="getProductResponse"> <wsdl:part name="parameters" element="tns:getProductResponse"> </wsdl:part> </wsdl:message> <wsdl:message name="getAllProducts"> <wsdl:part name="parameters" element="tns:getAllProducts"> </wsdl:part> </wsdl:message> <wsdl:portType name="ProductService"> <wsdl:operation name="getProduct"> <wsdl:input name="getProduct" message="tns:getProduct"> </wsdl:input> <wsdl:output name="getProductResponse" message="tns:getProductResponse"> </wsdl:output> </wsdl:operation> <wsdl:operation name="getAllProducts"> <wsdl:input name="getAllProducts" message="tns:getAllProducts"> </wsdl:input> <wsdl:output name="getAllProductsResponse" message="tns:getAllProductsResponse"> </wsdl:output> </wsdl:operation> </wsdl:portType> <wsdl:binding name="ProductServiceServiceSoapBinding" type="tns:ProductService"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="getProduct"> <soap:operation soapAction="" style="document"/> <wsdl:input name="getProduct"> <soap:body use="literal"/> </wsdl:input> <wsdl:output name="getProductResponse"> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="getAllProducts"> <soap:operation soapAction="" style="document"/> <wsdl:input name="getAllProducts"> <soap:body use="literal"/> </wsdl:input> <wsdl:output name="getAllProductsResponse"> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="ProductServiceService"> <wsdl:port name="ProductServicePort" binding="tns:ProductServiceServiceSoapBinding"> <soap:address location="http://localhost:8080/cxf-spring/services/productService"/> </wsdl:port> </wsdl:service> </wsdl:definitions>
In next tutorial (https://www.jeejava.com/consume-soap-webservice-using-apache-cxf-spring-maven/) we will see how to consume this service.
Thanks for reading.
The post Create SOAP Webservice using Apache CXF, Spring, Maven appeared first on JEE Tutorials.
Consume SOAP Webservice using Apache CXF, Spring, Maven
This tutorial will show you how we can consume SOAP based webservice using Apache cxf, Spring and Maven. For this tutorial we will create one maven standalone project in Eclipse. Please go through the tutorial first https://www.jeejava.com/create-soap-webservice-using-apache-cxf-spring-maven/
If you already have an idea on how to create a maven project in Eclipse will be great otherwise I will tell you here how to create a maven project in Eclipse.
Prerequisites
The following configurations are required in order to run the application
Eclipse Kepler
JDK 1.8(if you use jdk 1.7 then use Tomcat 7)
Tomcat 8
Have maven installed and configured
Apache cxf and Spring dependencies in pom.xml
Now we will see the below steps how to create a maven based spring project in Eclipse
First we will create service project
Step 1. Create a maven based web project in Eclipse
Go to File -> New -> Other. On popup window under Maven select Maven Project. Then click on Next. Select the workspace location – either default or browse the location. Click on Next. Now in next window select the row as highlighted from the below list of archtypes and click on Next button.
maven-arctype-webapp
Now enter the required fields (Group Id, Artifact Id) as shown below
Group Id : com.roytuts
Artifact Id : cxf-spring-client
Step 2. Modify the pom.xml file as shown below.
<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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.roytuts</groupId> <artifactId>cxf-spring-client</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>cxf-spring-client</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <cxf.version>3.0.4</cxf.version> <spring.version>4.0.5.RELEASE</spring.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-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> <plugins> <!-- maven compiler plugin definition --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.2</version> <configuration> <source>${jdk.version}</source> <target>${jdk.version}</target> </configuration> </plugin> <!-- Generate Java classes from WSDL during build --> <plugin> <groupId>org.apache.cxf</groupId> <artifactId>cxf-codegen-plugin</artifactId> <version>${cxf.version}</version> <executions> <execution> <id>generate-sources</id> <phase>generate-sources</phase> <configuration> <!-- which source folder the generated classes should be placed in a package --> <sourceRoot>${project.basedir}/src/main/java</sourceRoot> <wsdlOptions> <wsdlOption> <!-- put the wsdl file in this location --> <wsdl>${project.basedir}/src/main/resources/wsdl/ProductService.wsdl</wsdl> <extraargs> <extraarg>-client</extraarg> </extraargs> </wsdlOption> </wsdlOptions> </configuration> <goals> <goal>wsdl2java</goal> </goals> </execution> </executions> </plugin> <!-- Add generated sources - avoids having to copy generated sources to build location --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <executions> <execution> <id>add-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>${project.basedir}/src/main/java</source> </sources> </configuration> </execution> </executions> </plugin> <!-- Build the JAR with dependencies --> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> </plugin> </plugins> </build> </project>
Step 3. If you see JRE System Library[J2SE-1.5] then change the version by below process
Do right-click on the project and go to Build -> Configure build path, under Libraries tab click on JRE System Library[J2SE-1.5], click on Edit button and select the appropriate jdk 1.8 from the next window. Click on Finish then Ok.
Step 4. Now go to the project directory from command prompt and execute the command “mvn clean compile install” to generate the client or stub from wsdl file. You will see the following classes have been generated under src/main/java in com.roytuts.service package
Step 5. Now create a Java main class to test the client. Please make sure your server project (https://www.jeejava.com/create-soap-webservice-using-apache-cxf-spring-maven/) is running
package com.roytuts.client; import com.roytuts.service.Product; import com.roytuts.service.ProductService; import com.roytuts.service.ProductServiceService; public class ProductClient { public static void main(String[] args) { try { ProductServiceService productServiceSvc = new ProductServiceService(); ProductService productService = productServiceSvc.getProductServicePort(); Product product = productService.getProduct(101); System.out.println(product.getProductId()); System.out.println(product.getProductName()); System.out.println(product.getProductCatg()); } catch (Exception e) { e.printStackTrace(); } } }
Step 6. Now run the main class, you will see below output in the console
Feb 10, 2016 7:49:14 AM org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromWSDL INFO: Creating Service {http://service.roytuts.com/}ProductServiceService from WSDL: file:/D:/marsworkspace/cxf-spring-client/src/main/resources/wsdl/ProductService.wsdl 101 Laptop Electronics
Please read server project (https://www.jeejava.com/create-soap-webservice-using-apache-cxf-spring-maven/) then read client project.
Thanks for reading.
The post Consume SOAP Webservice using Apache CXF, Spring, Maven appeared first on JEE Tutorials.
Contract-first Webservice
This tutorial will show you how we can create and publish SOAP based webservice in Contract-first approach using Apache cxf, Spring and Maven. There are mainly two approaches to create the Webservice – Contract-first & Contract-last. The Contract-first approach tells us to create first WSDL and then create end-point interface and implementation class. The Contract-last approach tells us to create first end-point interface and implementation class then create WSDL file.
For this tutorial we will create one maven web project in Eclipse.
If you already have an idea on how to create a maven project in Eclipse will be great otherwise I will tell you here how to create a maven project in Eclipse.
Prerequisites
The following configurations are required in order to run the application
Eclipse Mars
JDK 1.8(if you use jdk 1.7 then use Tomcat 7)
Tomcat 8
Have maven installed and configured
Apache cxf and Spring dependencies in pom.xml
Now we will see the below steps how to create a maven based spring project in Eclipse
First we will create service project
Step 1. Create a maven based web project in Eclipse
Go to File -> New -> Other. On popup window under Maven select Maven Project. Then click on Next. Select the workspace location – either default or browse the location. Click on Next. Now in next window select the row as highlighted from the below list of archtypes and click on Next button.
maven-arctype-webapp
Now enter the required fields (Group Id, Artifact Id) as shown below
Group Id : com.roytuts
Artifact Id : soap-cxf-spring
Step 2. Modify the pom.xml file as shown below.
<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>com.roytuts</groupId> <artifactId>soap-cxf-spring</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>soap-cxf-spring</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <jdk.version>1.8</jdk.version> <cxf.version>3.1.5</cxf.version> <spring.version>4.1.6.RELEASE</spring.version> </properties> <dependencies> <!-- Spring dependencies --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <!-- Apache cxf dependencies --> <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> <!-- servlet & jsp --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.1.2</version> </dependency> </dependencies> <build> <finalName>soap-cxf-spring</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.2</version> <configuration> <source>${jdk.version}</source> <target>${jdk.version}</target> <configuration> <excludes> <exclude>/xsd/*</exclude> </excludes> </configuration> </configuration> </plugin> <!-- Generate Java classes from WSDL during build --> <plugin> <groupId>org.apache.cxf</groupId> <artifactId>cxf-codegen-plugin</artifactId> <version>${cxf.version}</version> <executions> <execution> <id>generate-sources</id> <phase>generate-sources</phase> <configuration> <!-- which source folder the generated classes should be placed in a package --> <sourceRoot>${project.basedir}/src/main/java</sourceRoot> <wsdlOptions> <wsdlOption> <!-- put the wsdl file in this location --> <wsdl>${project.basedir}/src/main/resources/wsdl/UserService.wsdl</wsdl> </wsdlOption> </wsdlOptions> </configuration> <goals> <goal>wsdl2java</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
Step 3. If you see JRE System Library[J2SE-1.5] then change the version by below process
Do right-click on the project and go to Build -> Configure build path, under Libraries tab click on JRE System Library[J2SE-1.5], click on Edit button and select the appropriate jdk 1.8 from the next window. Click on Finish then Ok.
Step 4. Create an XSD (schema definition file) under src/main/resources/xsd/user.xsd
For more information on XSD please read http://www.w3schools.com/xml/schema_example.asp http://www.codeguru.com/java/article.php/c13529/XSD-Tutorial-XML-Schemas-For-Beginners.htm
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="https://www.jeejava.com/UserService" targetNamespace="https://www.jeejava.com/UserService" elementFormDefault="qualified"> <xs:element name="getUserDetailsRequest"> <xs:complexType> <xs:sequence> <xs:element name="id" type="xs:int" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="getUserDetailsResponse"> <xs:complexType> <xs:sequence> <xs:element name="user" type="tns:user" /> </xs:sequence> </xs:complexType> </xs:element> <xs:complexType name="user"> <xs:sequence> <xs:element name="id" type="xs:int" /> <xs:element name="name" type="xs:string" /> <xs:element name="email" type="xs:string" /> <xs:element name="address" type="tns:address" /> </xs:sequence> </xs:complexType> <xs:complexType name="address"> <xs:sequence> <xs:element name="street" type="xs:string" /> <xs:element name="city" type="xs:string" /> <xs:element name="state" type="xs:string" /> <xs:element name="zip" type="xs:int" /> <xs:element name="country" type="xs:string" /> <xs:element name="addressType" type="tns:addressType" /> </xs:sequence> </xs:complexType> <xs:simpleType name="addressType"> <xs:restriction base="xs:string"> <xs:enumeration value="PERMANENT" /> <xs:enumeration value="COMMUNICATION" /> <xs:enumeration value="OFFICIAL" /> </xs:restriction> </xs:simpleType> </xs:schema>
In the above XSD we have basically two main elements – getUserDetailsRequest and getUserDetailsResponse. So getUserDetailsRequest will act as an input and getUserDetailsResponse will act as an output based on input.
Step 5. Now create a WSDL (web service definition language) file
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="https://www.jeejava.com/UserService" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" targetNamespace="https://www.jeejava.com/UserService"> <wsdl:types> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:import namespace="https://www.jeejava.com/UserService" schemaLocation="../xsd/user.xsd" /> </xsd:schema> </wsdl:types> <wsdl:message name="getUserDetailsRequest"> <wsdl:part element="tns:getUserDetailsRequest" name="getUserDetailsRequest" /> </wsdl:message> <wsdl:message name="getUserDetailsResponse"> <wsdl:part element="tns:getUserDetailsResponse" name="getUserDetailsResponse" /> </wsdl:message> <wsdl:portType name="UserPort"> <wsdl:operation name="getUserDetailsRequest"> <wsdl:input message="tns:getUserDetailsRequest" name="userDetailsInput" /> <wsdl:output message="tns:getUserDetailsResponse" name="userDetailsOutput" /> </wsdl:operation> </wsdl:portType> <wsdl:binding name="UserBinding" type="tns:UserPort"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="getUserDetailsRequest"> <soap:operation soapAction="" /> <wsdl:input name="userDetailsInput"> <soap:body use="literal" /> </wsdl:input> <wsdl:output name="userDetailsOutput"> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="UserService"> <wsdl:port binding="tns:UserBinding" name="UserService"> <soap:address location="/UserService" /> </wsdl:port> </wsdl:service> </wsdl:definitions>
In the definition file <wsdl:types/> defines the types of input and output requests, so in this file we have included the external XSD file user.xsd otherwise we had to define the types inside <wsdl:types/>.
In <wsdl:message name=”…”> the name is different from what is declared as element’s name in user.xsd file.
In <wsdl:part element=”…” name=”…”> the name must be same as what is declared as element’s name in user.xsd file.
Then we have <wsdl:portType/>, here the operation name could be as per your choice. The name in <wsdl:operation/> could be anything. The message in <wsdl:input/> or <wsdl:output/> must match with <wsdl:message/> name but the name in <wsdl:input/> or <wsdl:output/> could be anything.
The name in <wsdl:binding/> could be anything but type must match with the name in <wsdl:portType/>. Then inside <wsdl:operation/> we have <wsdl:input/> & <wsdl:output/> and their names must match with the names of <wsdl:input/> and <wsdl:output/> inside <wsdl:portType/>.
The name could be anything for <wsdl:service/>. The binding in <wsdl:port/> must be same as name of <wsdl:binding/>.
Lastly <soap:address/> where host & port have been removed because it will be running in the same server where deployed.
Step 6. Now build the maven project, you will see there are few classes generated in the package com.roytuts.userservice
Step 7. We are not using any database here to fetch data so we will create one mock data class which will give us data based on matching input
package com.roytuts.userservice.mock; import java.util.ArrayList; import java.util.List; import com.roytuts.userservice.Address; import com.roytuts.userservice.AddressType; import com.roytuts.userservice.User; public class UserMockData { private List<User> users = new ArrayList<User>(); public UserMockData() { User u1 = new User(); u1.setId(1); u1.setName("Sumit"); u1.setEmail("sumit.ghosh@email.com"); Address a1 = new Address(); a1.setStreet("Garfa"); a1.setCity("Kolkata"); a1.setState("WB"); a1.setCountry("India"); a1.setZip(700030); a1.setAddressType(AddressType.COMMUNICATION); u1.setAddress(a1); User u2 = new User(); u2.setId(2); u2.setName("Loku"); u2.setEmail("debabrata.poddar@email.com"); Address a2 = new Address(); a2.setStreet("Birati"); a2.setCity("Kolkata"); a2.setState("WB"); a2.setCountry("India"); a2.setZip(700130); a2.setAddressType(AddressType.COMMUNICATION); u2.setAddress(a2); User u3 = new User(); u3.setId(3); u3.setName("Souvik"); u3.setEmail("souvik.sanyal@email.com"); Address a3 = new Address(); a3.setStreet("Kalighat"); a3.setCity("Kolkata"); a3.setState("WB"); a3.setCountry("India"); a3.setZip(700150); a3.setAddressType(AddressType.COMMUNICATION); u3.setAddress(a3); User u4 = new User(); u4.setId(4); u4.setName("Liton"); u4.setEmail("liton.sarkar@email.com"); Address a4 = new Address(); a4.setStreet("Sukanta Nagar"); a4.setCity("Kolkata"); a4.setState("WB"); a4.setCountry("India"); a4.setZip(700098); a4.setAddressType(AddressType.COMMUNICATION); u4.setAddress(a4); User u5 = new User(); u5.setId(5); u5.setName("Debina"); u5.setEmail("debina.guha@email.com"); Address a5 = new Address(); a5.setStreet("Kestopur"); a5.setCity("Kolkata"); a5.setState("WB"); a5.setCountry("India"); a5.setZip(700091); a5.setAddressType(AddressType.COMMUNICATION); u5.setAddress(a5); users.add(u1); users.add(u2); users.add(u3); users.add(u4); users.add(u5); } public User getUser(int id) { for (User user : users) { if (id == user.getId()) { return user; } } return null; } }
Step 8. Maven already generated end-point interface for us, so we will create an implementation class
package com.roytuts.userservice.impl; import javax.jws.WebService; import com.roytuts.userservice.User; import com.roytuts.userservice.UserPort; import com.roytuts.userservice.mock.UserMockData; @WebService(endpointInterface = "com.roytuts.userservice.UserPort") public class UserPortImpl implements UserPort { private UserMockData mockData; public UserPortImpl(UserMockData mockData) { this.mockData = mockData; } @Override public User getUserDetailsRequest(final int id) { return mockData.getUser(id); } }
Step 9. Create spring-beans.xml file inside src/main/resources/spring/spring-beans.xml for configuring beans
<?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" /> <bean id="mockData" class="com.roytuts.userservice.mock.UserMockData" /> <bean id="userPort" class="com.roytuts.userservice.impl.UserPortImpl"> <constructor-arg ref="mockData" /> </bean> <jaxws:endpoint id="UserService" implementor="#userPort" address="/UserService" /> </beans>
In this spring configuration we have also defined the endpoint for webservice.
Step 10. Now complete the web.xml file as below.
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>Web Service</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/spring-beans.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <description>CXF Servlet</description> <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>
Step 11. Noe deploy the project into Tomcat 8 server, you will see the home page coming in the Eclipse default browser.
Step 12. Create a client class in package com.roytuts.userservice.client to test the service
package com.roytuts.userservice.client; import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; import com.roytuts.userservice.User; import com.roytuts.userservice.UserPort; public class UserClient { public static void main(String[] args) { final String endpointAddress = "http://localhost:8080/soap-cxf-spring/services/UserService"; JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); factory.setServiceClass(UserPort.class); // the SEI factory.setAddress(endpointAddress); UserPort port = (UserPort) factory.create(); User user = port.getUserDetailsRequest(2); System.out.println(user.getId()); System.out.println(user.getName()); System.out.println(user.getEmail()); System.out.println(user.getAddress().getAddressType()); System.out.println(user.getAddress().getStreet()); System.out.println(user.getAddress().getCity()); System.out.println(user.getAddress().getState()); System.out.println(user.getAddress().getCountry()); System.out.println(user.getAddress().getZip()); } }
Step 13. Run the client class you will get the output in console as shown below
Mar 05, 2016 8:27:49 AM org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromClass INFO: Creating Service {https://www.jeejava.com/UserService}UserPortService from class com.roytuts.userservice.UserPort 2 Loku debabrata.poddar@email.com COMMUNICATION Birati Kolkata WB India 700130
Thanks for reading.
The post Contract-first Webservice appeared first on JEE Tutorials.
SOAP Web Service with Mule ESB
In this tutorial I am going to show you how we can create SOAP web service in Mule ESB. We will use HTTP Connector as a request-response medium to interact with SOAP web service. The SOAP webservice here uses JAX-WS implementation.
You can see also REST Web Service with Mule ESB and Send data to remote REST web application using Mule ESB
Prerequisites
Mule Studio 3.x(Anypoint Studio) (Download from https://www.mulesoft.com/platform/studio)
Maven 3.2.1 (Download from https://maven.apache.org/download.cgi?Preferred=ftp://mirror.reverse.net/pub/apache/)
JDK 1.7 (Download from http://www.oracle.com/technetwork/java/javase/downloads/index.html)
Configure JDK, Maven and Mule Studio
Step 1. First install JDK
Step 2. Add the Java_Home/bin directory to your system’s PATH.
Step 3. After downloading Maven, extract it to a drive
Step 4. Add the M2_Home/bin directory to your system’s PATH.
Step 5. Download and extract Mule Studio to a drive
Step 6. Now start Mule Studio by clicking on AnypointStudio exe icon in the folder <physical drive>/AnypointStudio
Step 7. Once started, close the startup page
Step 8. In Mule Studio, go to Window -> Preferences. Expand Java, then click on Installed JREs. Add JDK 1.7 and select it. In expanded Java, click on Compiler and select the compiler level as 1.7
Step 9. Now expand Anypoint Studio and click on Maven Settings. Then select appropriate Maven installation home directory using Browse button.
Step 10. If you want you can input Default groupId for new projects, it will save your time every time when you want to create a new project.
Create Mule project in Mule Studio
Now we will see how to create a new project in Mule Studio(Anypoint Studio).
Step 1. In Anypoint Studio, go to File -> New -> Mule Project
Step 2. Input Project Name: mule, Runtime is by default selected, tick on Use Maven; here the artifactId is automatically picked up from the Project Name:, the Group Id is picked up from the Default groupId for new projects and version is also a default value.
Step 3. Click Next and verify the JDK, mainly select Use default JRE(currently ‘jdk1.7.0_x’)
Step 4. Click on Next and click on Finish.
Example
Step 1. Create the soap-with-mule.xml file under src/main/app directory and put the below file connector. While you create the xml file you will see on red mark on each file connector. Do not worry, red mark will be disappeared once you modify the xml file as given in Step 3.
Step 2. Open the soap-with-mule.xml file and click on Configuration XML view in the Editor
Step 3. Modify the soap-with-mule.xml file as shown below
<?xml version="1.0" encoding="UTF-8"?> <mule xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:cxf="http://www.mulesoft.org/schema/mule/cxf" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:spring="http://www.springframework.org/schema/beans" version="EE-3.5.1" 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-current.xsd http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd http://www.mulesoft.org/schema/mule/cxf http://www.mulesoft.org/schema/mule/cxf/current/mule-cxf.xsd http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd"> <flow name="soap-with-mule-flow" doc:name="soap-with-mule-flow"> <http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" path="soap" doc:name="HTTP" /> <cxf:jaxws-service serviceClass="com.roytuts.mule.soap.service.SoapService" doc:name="CXF" /> <component class="com.roytuts.mule.soap.service.impl.SoapServiceImpl" doc:name="Java" /> </flow> </mule>
In the above configuration we a Mule flow named as soap-with-mule-flow and inside this flow there is one http connector, which is acting as inboud-endpoint and handles request and response and there is another component called CXF SOAP, which is used to publish SOAP web service via using JAX-WS.
Step 4. Create a below service interface under directory src/main/java
package com.roytuts.mule.soap.service; import javax.jws.WebService; @WebService public interface SoapService { String sayHello(String name); }
Step 5. Create a below service implementation class under src/main/java
package com.roytuts.mule.soap.service.impl; import javax.jws.WebService; import com.roytuts.mule.soap.service.SoapService; @WebService(endpointInterface = "com.roytuts.mule.soap.service.SoapService") public class SoapServiceImpl implements SoapService { @Override public String sayHello(final String name) { return "Hello " + name + ", how are you?"; } }
Step 6. Running the application
Now do a right-click on the rest-with-mule.xml file and click on Run As -> Mule Application. Then you will see something like below in Console when the application runs
INFO 2016-09-30 16:06:34,590 [main] org.mule.DefaultMuleContext: ********************************************************************** * Application: mule * * OS encoding: Cp1252, Mule encoding: UTF-8 * * * * Agents Running: * * DevKit Extension Information * * Batch module default engine * * Clustering Agent * * JMX Agent * ********************************************************************** INFO 2016-09-30 16:06:34,590 [main] org.mule.module.launcher.MuleDeploymentService: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Started app 'mule' + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ INFO 2016-09-30 16:06:34,593 [main] org.mule.module.launcher.DeploymentDirectoryWatcher: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Mule is up and kicking (every 5000ms) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Once the application is up and running, try to hit the URL http://localhost:8081/soap?wsdl in the browser, you will get the below attached wsdl file
Step 7. Create web service client class under src/main/java to test the service.
package com.roytuts.mule.service.test; import java.net.MalformedURLException; import java.net.URL; import javax.xml.namespace.QName; import javax.xml.ws.Service; import com.roytuts.mule.soap.service.SoapService; public class SoapTest { /** * @param args * @throws MalformedURLException */ public static void main(String[] args) throws MalformedURLException { URL url = new URL("http://localhost:8081/soap?wsdl"); QName qname = new QName("http://service.soap.mule.roytuts.com/", "SoapServiceService"); Service service = Service.create(url, qname); SoapService soapService = service.getPort(SoapService.class); String response = soapService.sayHello("Soumitra"); System.out.println(response); } }
Step 7. Run the above client class, you will see below output in the console.
Hello Soumitra, how are you?
Thanks for reading.
The post SOAP Web Service with Mule ESB appeared first on JEE Tutorials.
Spring SOAP WebService Producers using Gradle
This tutorial will show you how we can create and publish SOAP based webservice in Contract-first approach using Spring and Gradle. There are mainly two approaches to create the Webservice – Contract-first & Contract-last. The Contract-first approach tells us to create first XSD/WSDL and then create end-point interface and implementation class. The Contract-last approach tells us to create first end-point interface and implementation class then create WSDL file. This example will show you mainly Spring SOAP Webservice Producers using Gradle, i.e., it will only publish or deploy the web service into the server.
Prerequisites
Java at least version 8 needs to be installed and configured
Gradle plugin needs to be installed into Eclipse
Gradle 4.x needs to installed and configured
Dependencies : Spring boot, wsdl
Creating and setting up Gradle project
Create gradle project called SpringBootSoapGradle using the following gradle dependencies
buildscript { ext { springBootVersion = '1.5.9.RELEASE' } repositories { mavenCentral() } dependencies { classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}" } } apply plugin: 'java' apply plugin: 'org.springframework.boot' repositories { mavenCentral() } sourceCompatibility = 1.8 targetCompatibility = 1.8 sourceSets.main.java.srcDirs "src/generated-sources/java" sourceSets.main.resources.excludes = ['user.xsd'] configurations { jaxb } dependencies { compile("org.springframework.boot:spring-boot-starter-web-services") compile("wsdl4j:wsdl4j:1.6.2") jaxb ( 'com.sun.xml.bind:jaxb-xjc:2.2.7', 'com.sun.xml.bind:jaxb-impl:2.2.7' ) } task jaxb { System.setProperty('javax.xml.accessExternalSchema', 'all') def jaxbTargetDir = file("src/generated-sources/java") doLast { jaxbTargetDir.mkdirs() ant.taskdef( name: 'xjc', classname: 'com.sun.tools.xjc.XJCTask', classpath: configurations.jaxb.asPath ) ant.jaxbTargetDir = jaxbTargetDir ant.xjc( destdir: '${jaxbTargetDir}', package: 'com.jeejava.jaxb', schema: 'src/main/resources/xsd/user.xsd' ) } } compileJava.dependsOn jaxb
Create main class
package com.jeejava.main; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication(scanBasePackages = "com.jeejava") public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
You should be able to build the blank project. Please ensure that the overall state is “BUILD SUCCESS” before continuing.
Note: You won’t be able to import Spring Boot dependencies until your project downloads all dependencies. So first create main class with empty main method and later when your project is successfully built then you can import required dependencies.
Execute command – gradle clean build on the project root directory from cmd prompt.
You will see the required jar files get downloaded and finally you would get “BUILD SUCCESSFUL” message.
Create an XSD (schema definition file) under src/main/resources/xsd/user.xsd
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="https://www.jeejava.com/UserService" targetNamespace="https://www.jeejava.com/UserService" elementFormDefault="qualified"> <xs:element name="getUserDetailsRequest"> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="getUserDetailsResponse"> <xs:complexType> <xs:sequence> <xs:element name="users" type="tns:user" minOccurs="0" maxOccurs="unbounded" /> </xs:sequence> </xs:complexType> </xs:element> <xs:complexType name="user"> <xs:sequence> <xs:element name="id" type="xs:int" /> <xs:element name="name" type="xs:string" /> <xs:element name="email" type="xs:string" /> <xs:element name="address" type="tns:address" /> </xs:sequence> </xs:complexType> <xs:complexType name="address"> <xs:sequence> <xs:element name="street" type="xs:string" /> <xs:element name="city" type="xs:string" /> <xs:element name="state" type="xs:string" /> <xs:element name="zip" type="xs:int" /> <xs:element name="country" type="xs:string" /> <xs:element name="addressType" type="tns:addressType" /> </xs:sequence> </xs:complexType> <xs:simpleType name="addressType"> <xs:restriction base="xs:string"> <xs:enumeration value="PERMANENT" /> <xs:enumeration value="COMMUNICATION" /> <xs:enumeration value="OFFICIAL" /> </xs:restriction> </xs:simpleType> </xs:schema>
In the above XSD we have basically two main elements – getUserDetailsRequest and getUserDetailsResponse. So getUserDetailsRequest will act as an input and getUserDetailsResponse will act as an output based on input.
Generate domain classes based on an XML schema
The next step is to generate Java classes from the XSD file. The right approach is do this automatically during build time using a gradle plugin. For this you need to write below code(which is already there in the above build file) into build.gradle file. As gradle does not have a JAXB plugin (yet), it involves an ant task, which makes it a bit more complex than in maven.
sourceSets.main.java.srcDirs "src/generated-sources/java" sourceSets.main.resources.excludes = ['user.xsd'] configurations { jaxb } dependencies { compile("org.springframework.boot:spring-boot-starter-web-services") compile("wsdl4j:wsdl4j:1.6.2") jaxb ( 'com.sun.xml.bind:jaxb-xjc:2.2.7', 'com.sun.xml.bind:jaxb-impl:2.2.7' ) } task jaxb { System.setProperty('javax.xml.accessExternalSchema', 'all') def jaxbTargetDir = file("src/generated-sources/java") doLast { jaxbTargetDir.mkdirs() ant.taskdef( name: 'xjc', classname: 'com.sun.tools.xjc.XJCTask', classpath: configurations.jaxb.asPath ) ant.jaxbTargetDir = jaxbTargetDir ant.xjc( destdir: '${jaxbTargetDir}', package: 'com.jeejava.jaxb', schema: 'src/main/resources/xsd/user.xsd' ) } } compileJava.dependsOn jaxb
Create user repository
In order to provide data to the web service, create a user repository. In this guide we create a dummy user repository implementation with dummy data.
package com.jeejava.repository; import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Component; import com.jeejava.jaxb.Address; import com.jeejava.jaxb.AddressType; import com.jeejava.jaxb.User; @Component public class UserRepository { private List<User> users = new ArrayList<User>(); public UserRepository() { User u1 = new User(); u1.setId(1); u1.setName("Sumit Ghosh"); u1.setEmail("sumit.ghosh@email.com"); Address a1 = new Address(); a1.setStreet("Garfa"); a1.setCity("Kolkata"); a1.setState("WB"); a1.setCountry("India"); a1.setZip(700030); a1.setAddressType(AddressType.COMMUNICATION); u1.setAddress(a1); User u2 = new User(); u2.setId(2); u2.setName("Loku Poddar"); u2.setEmail("debabrata.poddar@email.com"); Address a2 = new Address(); a2.setStreet("Birati"); a2.setCity("Kolkata"); a2.setState("WB"); a2.setCountry("India"); a2.setZip(700130); a2.setAddressType(AddressType.COMMUNICATION); u2.setAddress(a2); User u3 = new User(); u3.setId(3); u3.setName("Souvik Sanyal"); u3.setEmail("souvik.sanyal@email.com"); Address a3 = new Address(); a3.setStreet("Kalighat"); a3.setCity("Kolkata"); a3.setState("WB"); a3.setCountry("India"); a3.setZip(700150); a3.setAddressType(AddressType.COMMUNICATION); u3.setAddress(a3); User u4 = new User(); u4.setId(4); u4.setName("Liton Sarkar"); u4.setEmail("liton.sarkar@email.com"); Address a4 = new Address(); a4.setStreet("Sukanta Nagar"); a4.setCity("Kolkata"); a4.setState("WB"); a4.setCountry("India"); a4.setZip(700098); a4.setAddressType(AddressType.COMMUNICATION); u4.setAddress(a4); User u5 = new User(); u5.setId(5); u5.setName("Rushikesh Mukund Fanse"); u5.setEmail("rushikesh.fanse@email.com"); Address a5 = new Address(); a5.setStreet("Nasik"); a5.setCity("Mumbai"); a5.setState("MH"); a5.setCountry("India"); a5.setZip(400091); a5.setAddressType(AddressType.COMMUNICATION); u5.setAddress(a5); users.add(u1); users.add(u2); users.add(u3); users.add(u4); users.add(u5); } public List<User> getUsers(String name) { List<User> userList = new ArrayList<>(); for (User user : users) { if (user.getName().toLowerCase().contains(name.toLowerCase())) { userList.add(user); } } return userList; } }
Create user service endpoint
To create a service endpoint, we only need a POJO with a few Spring WS annotations to handle the incoming SOAP requests.
package com.jeejava.soap; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.ws.server.endpoint.annotation.Endpoint; import org.springframework.ws.server.endpoint.annotation.PayloadRoot; import org.springframework.ws.server.endpoint.annotation.RequestPayload; import org.springframework.ws.server.endpoint.annotation.ResponsePayload; import com.jeejava.jaxb.GetUserDetailsRequest; import com.jeejava.jaxb.GetUserDetailsResponse; import com.jeejava.repository.UserRepository; @Endpoint public class UserServiceEndpoint { private final String NAMESPACE = "https://www.jeejava.com/UserService"; @Autowired private UserRepository userRepository; @PayloadRoot(namespace = NAMESPACE, localPart = "getUserDetailsRequest") @ResponsePayload public GetUserDetailsResponse getUser(@RequestPayload final GetUserDetailsRequest request) { GetUserDetailsResponse response = new GetUserDetailsResponse(); response.getUsers().addAll(userRepository.getUsers(request.getName())); return response; } }
@Endpoint
registers the class with Spring WS as a potential candidate for processing incoming SOAP messages.
@PayloadRoot
is then used by Spring WS to pick the handler method based on the message’s namespace and localPart.
@RequestPayload
indicates that the incoming message will be mapped to the method’s request parameter.
The @ResponsePayload
annotation makes Spring WS map the returned value to the response payload.
Configure web service beans
Create a new class with Spring WS related beans configuration:
package com.jeejava.config; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.ws.config.annotation.EnableWs; import org.springframework.ws.config.annotation.WsConfigurerAdapter; import org.springframework.ws.transport.http.MessageDispatcherServlet; import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition; import org.springframework.xml.xsd.SimpleXsdSchema; import org.springframework.xml.xsd.XsdSchema; @EnableWs @Configuration public class WebServiceConfig extends WsConfigurerAdapter { @Bean public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) { MessageDispatcherServlet servlet = new MessageDispatcherServlet(); servlet.setApplicationContext(applicationContext); servlet.setTransformWsdlLocations(true); return new ServletRegistrationBean(servlet, "/ws/*"); } @Bean(name = "users") public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema countriesSchema) { DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition(); wsdl11Definition.setPortTypeName("UserPort"); wsdl11Definition.setLocationUri("/ws"); wsdl11Definition.setTargetNamespace("https://www.jeejava.com/UserService"); wsdl11Definition.setSchema(countriesSchema); return wsdl11Definition; } @Bean public XsdSchema helloSchema() { return new SimpleXsdSchema(new ClassPathResource("xsd/user.xsd")); } }
Spring WS uses a different servlet type for handling SOAP messages: MessageDispatcherServlet. It is important to inject and set ApplicationContext to MessageDispatcherServlet. Without that, Spring WS will not detect Spring beans automatically.
By naming this bean messageDispatcherServlet, it does not replace Spring Boot’s default DispatcherServlet bean.
DefaultMethodEndpointAdapter configures annotation driven Spring WS programming model. This makes it possible to use the various annotations like @Endpoint mentioned earlier.
DefaultWsdl11Definition exposes a standard WSDL 1.1 using XsdSchema.
It’s important to notice that we need to specify bean names for MessageDispatcherServlet and DefaultWsdl11Definition. Bean names determine the URL under which web service and the generated WSDL file is available. In this case, the WSDL will be available under http://<host>:<port>/ws/user.wsdl
.
Change default port
We don’t want tomcat server in spring boot application to be started on random port, so set the server port in SpringBootWebSocketAngularJSGradle/src/main/resources/application.properties
server.port=9999
Test the application
Open SOAPUI and use the WSDL URL as http://localhost:9999/ws/users.wsdl
and Endpoint as http://localhost:9999/ws
Now request with below input
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:user="https://www.jeejava.com/UserService"> <soapenv:Header/> <soapenv:Body> <user:getUserDetailsRequest> <user:name>l</user:name> </user:getUserDetailsRequest> </soapenv:Body> </soapenv:Envelope>
The corresponding output you should get
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Header/> <SOAP-ENV:Body> <ns2:getUserDetailsResponse xmlns:ns2="https://www.jeejava.com/UserService"> <ns2:users> <ns2:id>2</ns2:id> <ns2:name>Loku Poddar</ns2:name> <ns2:email>debabrata.poddar@email.com</ns2:email> <ns2:address> <ns2:street>Birati</ns2:street> <ns2:city>Kolkata</ns2:city> <ns2:state>WB</ns2:state> <ns2:zip>700130</ns2:zip> <ns2:country>India</ns2:country> <ns2:addressType>COMMUNICATION</ns2:addressType> </ns2:address> </ns2:users> <ns2:users> <ns2:id>3</ns2:id> <ns2:name>Souvik Sanyal</ns2:name> <ns2:email>souvik.sanyal@email.com</ns2:email> <ns2:address> <ns2:street>Kalighat</ns2:street> <ns2:city>Kolkata</ns2:city> <ns2:state>WB</ns2:state> <ns2:zip>700150</ns2:zip> <ns2:country>India</ns2:country> <ns2:addressType>COMMUNICATION</ns2:addressType> </ns2:address> </ns2:users> <ns2:users> <ns2:id>4</ns2:id> <ns2:name>Liton Sarkar</ns2:name> <ns2:email>liton.sarkar@email.com</ns2:email> <ns2:address> <ns2:street>Sukanta Nagar</ns2:street> <ns2:city>Kolkata</ns2:city> <ns2:state>WB</ns2:state> <ns2:zip>700098</ns2:zip> <ns2:country>India</ns2:country> <ns2:addressType>COMMUNICATION</ns2:addressType> </ns2:address> </ns2:users> </ns2:getUserDetailsResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
Now request with below input
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:user="https://www.jeejava.com/UserService"> <soapenv:Header/> <soapenv:Body> <user:getUserDetailsRequest> <user:name>souvik</user:name> </user:getUserDetailsRequest> </soapenv:Body> </soapenv:Envelope>
The corresponding output you should get
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Header/> <SOAP-ENV:Body> <ns2:getUserDetailsResponse xmlns:ns2="https://www.jeejava.com/UserService"> <ns2:users> <ns2:id>3</ns2:id> <ns2:name>Souvik Sanyal</ns2:name> <ns2:email>souvik.sanyal@email.com</ns2:email> <ns2:address> <ns2:street>Kalighat</ns2:street> <ns2:city>Kolkata</ns2:city> <ns2:state>WB</ns2:state> <ns2:zip>700150</ns2:zip> <ns2:country>India</ns2:country> <ns2:addressType>COMMUNICATION</ns2:addressType> </ns2:address> </ns2:users> </ns2:getUserDetailsResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
If you face issue like “java.lang.NoClassDefFoundError: javax/activation/DataSource” or “java.lang.Error: java.lang.reflect.InvocationTargetException” in JDK 9 then add below line to gradle.properties
file and build
org.gradle.jvmargs=--add-modules=java.xml.bind,java.activation
Now while refreshing project in Eclipse, if you face problem creating virtual machine then you can remove the above line from gradle.properties
after build and refresh the project in Eclipse.
Thanks for reading.
The post Spring SOAP WebService Producers using Gradle appeared first on JEE Tutorials.
Spring SOAP WebService Consumers using Gradle
Please read Spring SOAP WebService Producers using Gradle before continuing this tutorial.
This tutorial will show you how we can consume SOAP based web service using Spring and Gradle. Please get the WSDL file from http://localhost:9999/ws/users.wsdl
and you can save the downloaded file under src/main/resources/wsdl
directory. This example shows only Spring SOAP web service consumers using Gradle to consume the already deployed or published service.
Prerequisites
Java at least version 8 needs to be installed and configured
Gradle plugin needs to be installed into Eclipse
Gradle 4.x needs to installed and configured
Dependencies : cxf
Creating and setting up Gradle project
Create gradle project called SpringBootSoapGradle using the following gradle dependencies
buildscript { repositories { mavenCentral() } dependencies { classpath 'no.nils:wsdl2java:0.10' } } apply plugin: 'java' apply plugin: 'no.nils.wsdl2java' repositories { mavenCentral() } sourceCompatibility = 1.8 targetCompatibility = 1.8 wsdl2javaExt { cxfVersion = "3.1.10" } wsdl2java{ generatedWsdlDir = file("${projectDir}/src/main/service") wsdlDir=file("${projectDir}/src/main/resources/wsdl/") wsdlsToGenerate = [ [file("${projectDir}/src/main/resources/wsdl/users.wsdl")] ] } compileJava.dependsOn wsdl2java
Build the project
Execute command – “gradle clean build” on the project root directory from cmd prompt.
You will see the required jar files get downloaded and finally you would get “BUILD SUCCESSFUL” message.
Create main class
package com.jeejava.soap.client; import com.jeejava.userservice.GetUserDetailsRequest; import com.jeejava.userservice.GetUserDetailsResponse; import com.jeejava.userservice.User; import com.jeejava.userservice.UserPort; import com.jeejava.userservice.UserPortService; public class UserServiceClient { public static void main(String[] args) { UserPort userPort = new UserPortService().getUserPortSoap11(); GetUserDetailsRequest request = new GetUserDetailsRequest(); request.setName("souvik"); GetUserDetailsResponse response = userPort.getUserDetails(request); for (User user : response.getUsers()) { System.out.println(user.getId() + ", " + user.getName() + ", " + user.getEmail() + ", [" + user.getAddress().getStreet() + ", " + user.getAddress().getCity() + ", " + user.getAddress().getState() + ", " + user.getAddress().getZip() + ", " + user.getAddress().getCountry() + ", " + user.getAddress().getAddressType() + "]"); } System.out.println("------------------------------------------------------------------------------------------------"); request.setName("l"); response = userPort.getUserDetails(request); for (User user : response.getUsers()) { System.out.println(user.getId() + ", " + user.getName() + ", " + user.getEmail() + ", [" + user.getAddress().getStreet() + ", " + user.getAddress().getCity() + ", " + user.getAddress().getState() + ", " + user.getAddress().getZip() + ", " + user.getAddress().getCountry() + ", " + user.getAddress().getAddressType() + "]"); } } }
Test the application
Make sure first server application is running. Then run the above main class, you will get below output in the console.
3, Souvik Sanyal, souvik.sanyal@email.com, [Kalighat, Kolkata, WB, 700150, India, COMMUNICATION] ------------------------------------------------------------------------------------------------ 2, Loku Poddar, debabrata.poddar@email.com, [Birati, Kolkata, WB, 700130, India, COMMUNICATION] 3, Souvik Sanyal, souvik.sanyal@email.com, [Kalighat, Kolkata, WB, 700150, India, COMMUNICATION] 4, Liton Sarkar, liton.sarkar@email.com, [Sukanta Nagar, Kolkata, WB, 700098, India, COMMUNICATION]
Thanks for reading.
The post Spring SOAP WebService Consumers using Gradle appeared first on JEE Tutorials.
How to do a SOAP Web Service call from Java class
Introduction
This example will show you how to do a SOAP web service call from Java class. Normally you would use the web service library for invoking the SOAP service but in some cases this could be useful and quick. For example, you may have problems generating a client proxy with a web service library or if you only need some small specific parts of the response. It is just a SOAP call over HTTP from a plain piece of Java code without using any Java library. In fact you can invoke SOAP service from any language being web service platform independent.
Now in order to consume the service or SOAP web service call from Java class, we must have the service deployed somewhere. So please read Spring SOAP WebService Producers using Gradle before consuming this SOAP service. We will create here client which will consume the service in the given link. If you want to use library to consume the service then you can read Spring SOAP WebService Consumers using Gradle
Prerequisites
Knowledge of Java, SOAP, Java 1.8
Spring SOAP WebService Producers using Gradle
Example with Source Code
Finding the WSDL
In order to SOAP web service call from Java class first open the WSDl file at http://localhost:9999/ws/users.wsdl from tutorial Spring SOAP WebService Producers using Gradle.
In the WSDL file given in the above link, look for XSD, SOAP Operation and SOAP address location in the WSDL file. So you will find SOAP request name getUserDetailsRequest and SOAP response name getUserDetailsResponse. Also check for the input parameter(s) for request. Here we see only one parameter called name, which is of string type.
Request XML
We don’t need to build the response XML structure using Java code because we will get it from the server side but we need to build the request XML structure because we need to provide it as an input to the SOAP service.
Therefore if we build the request XML structure, it will look similar to below:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<getUserDetailsRequest xmlns="http://www.jeejava.com/UserService">
<name>Liton Sarkar</name>
</getUserDetailsRequest>
</soapenv:Body>
</soapenv:Envelope>
SOAP Address
Now find the SOAP address location, which is used as an endpoint URL for SOAP service and at this endpoint we will connect using Java’s HttpURLConnection API.
Here the endpoint URL is http://localhost:9999/ws
SOAP Operation
Next is to find the operation name, which will be used as a SOAP Action. Here it is getUserDetails.
Creating SOAP Client
Now we have identified all the required things and are ready to create the client class.
package com.jeejava.soap.client;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class SoapClient {
public static void main(String[] args) throws IOException {
// Code to make a webservice HTTP request
String responseString = "";
String outputString = "";
String wsEndPoint = "http://localhost:9999/ws";
URL url = new URL(wsEndPoint);
URLConnection connection = url.openConnection();
HttpURLConnection httpConn = (HttpURLConnection) connection;
ByteArrayOutputStream bout = new ByteArrayOutputStream();
String xmlInput = "<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header/><soapenv:Body><getUserDetailsRequest xmlns="http://www.jeejava.com/UserService"><name>Liton Sarkar</name></getUserDetailsRequest></soapenv:Body></soapenv:Envelope>";
byte[] buffer = new byte[xmlInput.length()];
buffer = xmlInput.getBytes();
bout.write(buffer);
byte[] b = bout.toByteArray();
String SOAPAction = "getUserDetails";
httpConn.setRequestProperty("Content-Length", String.valueOf(b.length));
httpConn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
httpConn.setRequestProperty("SOAPAction", SOAPAction);
httpConn.setRequestMethod("POST");
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
OutputStream out = httpConn.getOutputStream();
// Write the content of the request to the outputstream of the HTTP
// Connection.
out.write(b);
out.close();
// Ready with sending the request.
// Read the response.
InputStreamReader isr = new InputStreamReader(httpConn.getInputStream(), Charset.forName("UTF-8"));
BufferedReader in = new BufferedReader(isr);
// Write the SOAP message response to a String.
while ((responseString = in.readLine()) != null) {
outputString = outputString + responseString;
}
// Write the SOAP message formatted to the console.
String formattedSOAPResponse = formatXML(outputString);
System.out.println(formattedSOAPResponse);
}
// format the XML in pretty String
private static String formatXML(String unformattedXml) {
try {
Document document = parseXmlFile(unformattedXml);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
transformerFactory.setAttribute("indent-number", 3);
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(document);
StreamResult xmlOutput = new StreamResult(new StringWriter());
transformer.transform(source, xmlOutput);
return xmlOutput.getWriter().toString();
} catch (TransformerException e) {
throw new RuntimeException(e);
}
}
// parse XML
private static Document parseXmlFile(String in) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(in));
return db.parse(is);
} catch (IOException | ParserConfigurationException | SAXException e) {
throw new RuntimeException(e);
}
}
}
Testing the Application
Now when you run the above Java class you will see the below output in the console.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ns2:getUserDetailsResponse xmlns:ns2="http://www.jeejava.com/UserService">
<ns2:users>
<ns2:id>4</ns2:id>
<ns2:name>Liton Sarkar</ns2:name>
<ns2:email>liton.sarkar@email.com</ns2:email>
<ns2:address>
<ns2:street>Sukanta Nagar</ns2:street>
<ns2:city>Kolkata</ns2:city>
<ns2:state>WB</ns2:state>
<ns2:zip>700098</ns2:zip>
<ns2:country>India</ns2:country>
<ns2:addressType>COMMUNICATION</ns2:addressType>
</ns2:address>
</ns2:users>
</ns2:getUserDetailsResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
That’s all. Thanks for reading.
The post How to do a SOAP Web Service call from Java class appeared first on JEE Tutorials.
SOAP over HTTPS with Client Certificate Authentication
Introduction
The tutorial, SOAP over HTTPS with client certificate authentication, will show you how we can use client certificate to handshake with server along with basic authentication for consuming the service. We have also seen how to authenticate by sending authentication information over http headers in SOAP web service but here we will use client certificate (jks file) as a security mechanism. Even you can use header authentication along with client certificate to make more secure.
I will show here both server side code or service and client side code so that server expects client to establish communication through certificate authentication. Here to consume the service you will be given client certificate (extention might be .crt or .der or .p12 or anything else), password for this certificate and username/password for basic authentication (in case if you need also header authentication).
You may also like to read Spring SOAP web service producers and Spring SOAP web service consumers
Prerequisites
Knowledge of Java, SOAP
Softwares
Eclipse
JDK 1.8
Gradle 4.x
Spring Boot
Example with Source Code
Here actually we will create soap web service producer and soap web service consumer to finish the example about soap over https with client certificate authentication.
SOAP Service Producer
Setting up Gradle Project
Create gradle project called spring-boot-soap-https-authentication using the following gradle dependencies. In the below build script we have defined jaxb configurations in order to generate jaxb classes from xsd files.
You may also refer to the similar example Spring SOAP Web Service Producers
Currently we do not have any jaxb plugin available in Gradle. That’s why we have written one task called jaxb to generate the jaxb classes from xsd files. We have specified the folder src/generated-sources/java where the jxb classes should be generated under the package com.jeejava.jaxb.
buildscript {
ext {
springBootVersion = '1.5.9.RELEASE';
}
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
allprojects {
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
sourceSets.main.java.srcDirs "src/generated-sources/java"
sourceSets.main.resources.excludes = ['temperature.xsd']
configurations {
jaxb
}
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web-services:${springBootVersion}")
compile("wsdl4j:wsdl4j:1.6.2")
jaxb (
'com.sun.xml.bind:jaxb-xjc:2.2.7',
'com.sun.xml.bind:jaxb-impl:2.2.7'
)
}
task jaxb {
System.setProperty('javax.xml.accessExternalSchema', 'all')
def jaxbTargetDir = file("src/generated-sources/java")
doLast {
jaxbTargetDir.mkdirs()
ant.taskdef(
name: 'xjc',
classname: 'com.sun.tools.xjc.XJCTask',
classpath: configurations.jaxb.asPath
)
ant.jaxbTargetDir = jaxbTargetDir
ant.xjc(
destdir: '${jaxbTargetDir}',
package: 'com.jeejava.jaxb',
schema: 'src/main/resources/xsd/temperature.xsd'
)
}
}
compileJava.dependsOn jaxb
You should be able to build the blank project. Please ensure that the overall state is “BUILD SUCCESS” before continuing.
If you get any exception like “Unable to find main class”, then create a main class Application under package com.jeejava.main.
Note: You won’t be able to import Spring Boot dependencies in main class until your project downloads all dependencies. So first create main class with empty main method and later when your project is successfully built then you can import required dependencies.
Recommended reading:
Authentication example in JAX-WS webservice
SunCertPathBuilderException: unable to find valid certification path to requested target
Using SSL(Secure Socket Layer) in JAX-WS webservice
Creating XSD
Create an XSD (schema definition file) under src/main/resources/xsd/temperature.xsd.
As you see in the below xsd file we have two input requests and two output responses because we want to convert temperature from Celsius to Fahrenheit.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://www.example.com/TemperatureService" targetNamespace="http://www.example.com/TemperatureService"
elementFormDefault="qualified">
<xs:element name="GetCelsiusRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="celcius" type="xs:double" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="GetCelsiusResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="fahrenheit" type="xs:double" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
SOAP Service Configuration
Spring WS uses a different servlet type for handling SOAP messages: MessageDispatcherServlet. It is important to inject and set ApplicationContext to MessageDispatcherServlet. Without this, Spring WS will not detect Spring beans automatically.
By naming this bean messageDispatcherServlet, it does not replace Spring Boot’s default DispatcherServlet bean.
DefaultMethodEndpointAdapter configures annotation driven Spring WS programming model. This makes it possible to use the various annotations like @Endpoint mentioned earlier.
DefaultWsdl11Definition exposes a standard WSDL 1.1 using XsdSchema.
It’s important to notice that we need to specify bean names for MessageDispatcherServlet and DefaultWsdl11Definition. Bean names determine the URL under which web service and the generated WSDL file is available.
In this case, the WSDL will be available under http://<host>:<port>/ws/temp.wsdl.
package com.jeejava.config;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.ws.config.annotation.EnableWs;
import org.springframework.ws.config.annotation.WsConfigurerAdapter;
import org.springframework.ws.transport.http.MessageDispatcherServlet;
import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition;
import org.springframework.xml.xsd.SimpleXsdSchema;
import org.springframework.xml.xsd.XsdSchema;
@EnableWs
@Configuration
public class SoapWebServiceConfig extends WsConfigurerAdapter {
@Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/ws/*");
}
@Bean(name = "temp")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema countriesSchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("TempPort");
wsdl11Definition.setLocationUri("/ws");
wsdl11Definition.setTargetNamespace("http://www.example.com/TemperatureService");
wsdl11Definition.setSchema(countriesSchema);
return wsdl11Definition;
}
@Bean
public XsdSchema helloSchema() {
return new SimpleXsdSchema(new ClassPathResource("xsd/temperature.xsd"));
}
}
Creating Service
Create service layer class TemperatureService for converting temperature from fahrenheit to celcius and celcius to fahrenheit.
This class has one method – convertCelsiusToFahrenheit converts celsius temperature to fahrenheit temperature.
package com.jeejava.service;
import org.springframework.stereotype.Service;
@Service
public class TemperatureService {
public double convertCelsiusToFahrenheit(final double celsius) {
double fahrenheit = (9.0 / 5.0) * celsius + 32;
return fahrenheit;
}
}
Creating Service Endpoint
To create a service endpoint, we only need a POJO with a few Spring WS annotations to handle the incoming SOAP requests.
@Endpoint registers the class with Spring WS as a potential candidate for processing incoming SOAP messages.
@PayloadRoot is then used by Spring WS to pick the handler method based on the message’s namespace and localPart.
@RequestPayload indicates that the incoming message will be mapped to the method’s request parameter.
The @ResponsePayload annotation makes Spring WS map the returned value to the response payload.
package com.jeejava.soap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
import org.springframework.ws.server.endpoint.annotation.RequestPayload;
import org.springframework.ws.server.endpoint.annotation.ResponsePayload;
import com.jeejava.jaxb.GetCelsiusRequest;
import com.jeejava.jaxb.GetCelsiusResponse;
import com.jeejava.service.TemperatureService;
@Endpoint
public class TemperatureServiceEndpoint {
final String NAMESPACE = "http://www.example.com/TemperatureService";
@Autowired
TemperatureService temperatureService;
@ResponsePayload
@PayloadRoot(namespace = NAMESPACE, localPart = "GetCelsiusRequest")
public GetCelsiusResponse getFahrenheit(@RequestPayload final GetCelsiusRequest input) {
GetCelsiusResponse response = new GetCelsiusResponse();
response.setFahrenheit(temperatureService.convertCelsiusToFahrenheit(input.getCelcius()));
return response;
}
}
Changing Server Port
We don’t want tomcat server in spring boot application to be started on random port, so set the server port in src/main/resources/application.properties
server.port=9999
Testing the Application
Open SOAPUI and use the WSDL URL as http://localhost:9999/ws/temp.wsdl and Endpoint as http://localhost:9999/ws
Enabling HTTPS in SOAP
As we need to secure the service with client certificate and making it only available over HTTPS.
First we need to get an SSL certificate. Either you have to get it self-signed or from certificate authority.
We can easily generate self-signed certificate using Java’s built-in keytool utility.
Let’s generate a self-signed certificate using the following command in cmd prompt.
If you have already setup environment variable for Java then you may be able to generate from any path location or you may navigate to the jdk bin directory from cmd prompt and execute the following command. Please note that password must be at least six characters.
keytool -genkey -keyalg RSA -alias selfsigned -keystore certificate.jks -storepass changeit -validity 360
When you type the above command you will be asked few questions and you may answer them similar to as shown in the below image

So you have successfully generated a keystore called certificate.jks with a newly generated certificate in it with certificate alias selfsigned and password changeit and validity for this certificate is 360 days.
Now check the generated certificate or keystore using the following command from command prompt.
keytool -list -keystore certificate.jks -storepass changeit
You will see the below information in the cmd prompt as shown in the below image

Then we use this certificate in our temperature service by declaring the followings in the default application.properties in src/main/resources directory.
Now you see we have updated port from 9999 to 8443 to use https instead of http protocol.
Please make sure you have put the certificate.jks file under classpath src/main/resources directory.
server.port=8443
server.ssl.key-store=classpath:certificate.jks
server.ssl.key-store-password=changeit
server.ssl.key-alias=selfsigned
Now run the application and you would be able to see the WSDL file at https://localhost:8443/ws/temp.wsdl and Endpoint is https://localhost:8443/ws.
So when you access it in browser, the browser will complain that it is using a self-signed certificate. This secure service is now accessible by any client. Therefore we need to generate client certificate as well so that only particular that client will be able to access the service.
Authenticate using client certificate
Now let’s create separate certificate for client. Here we will access the service from Java code, so we will create client certificate for Java client.
If you access the service from other clients as well then create certificate for each client you are accessing from.
Use the following command in cmd prompt in order to generate client certificate for Java client:
keytool -genkey -keyalg RSA -alias javaclient -keystore javaclient.jks -storepass changeit -validity 360
So when prompt for several questions then give the same answers you had give while generating the server certificate.
Now we need to extract the certificate from truststore for Java client because we need to import this certificate for remote authentication also.
keytool -export -alias javaclient -file javaclient.crt -keystore javaclient.jks -storepass changeit
So the certificate file javaclient.crt gets generated.
Now we have to add the above generated certificate to keystore in order to establish the handshake between Java client and soap server.
Use below command in order to do it
keytool -import -alias javaclient -file javaclient.crt -keystore truststore.jks -storepass changeit
Once prompted for Trust this certificate? [no]: . Type yes.

Now check the truststore should have javaclient certificate using below command:

Now we need to configure also javaclient truststore at server side so that server knows who is trying to establish connection among themselves. So the whole application.properties file looks similar to below.
server.port=8443
server.ssl.key-store=classpath:certificate.jks
server.ssl.key-store-password=changeit
server.ssl.key-alias=selfsigned
server.ssl.trust-store=classpath:truststore.jks
server.ssl.trust-store-password=changeit
server.ssl.client-auth=need
It is mandatory to set the server.ssl.client-auth=need
in order to make the client authentication mandatory.
So now you neither be able to view wsdl nor be able to connect to service from anywhere except Java client.
The final project structure for server side or soap service producer for soap over https with client certificate authentication is given below

So we are done with the server side code for soap over https with client certificate authentication. We have also generated required certificates for server and client.
SOAP Service Consumer
Now we will create soap web service consumer for consume the above service.
Setting up Gradle Project
Now create and setup the project using below build script. We have the temperature wsdl file from the above service.
For more information on generating stub from wsdl in gradle you may read here and here.
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'no.nils:wsdl2java:0.10'
}
}
apply plugin: 'java'
apply plugin: 'no.nils.wsdl2java'
repositories {
mavenCentral()
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
wsdl2javaExt {
cxfVersion = "3.1.10"
}
wsdl2java{
generatedWsdlDir = file("${projectDir}/src/main/service")
wsdlDir=file("${projectDir}/src/main/resources/wsdl/")
wsdlsToGenerate = [
[file("${projectDir}/src/main/resources/wsdl/temperature.wsdl")]
]
}
compileJava.dependsOn wsdl2java
The temperature.wsdl file content is given below
<?xml version="1.0" encoding="UTF-8" standalone="no"?><wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:sch="http://www.example.com/TemperatureService" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.example.com/TemperatureService" targetNamespace="http://www.example.com/TemperatureService">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.example.com/TemperatureService">
<xs:element name="GetCelsiusRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="celcius" type="xs:double"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="GetCelsiusResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="fahrenheit" type="xs:double"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<wsdl:message name="GetCelsiusResponse">
<wsdl:part element="tns:GetCelsiusResponse" name="GetCelsiusResponse">
</wsdl:part>
</wsdl:message>
<wsdl:message name="GetCelsiusRequest">
<wsdl:part element="tns:GetCelsiusRequest" name="GetCelsiusRequest">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="TempPort">
<wsdl:operation name="GetCelsius">
<wsdl:input message="tns:GetCelsiusRequest" name="GetCelsiusRequest">
</wsdl:input>
<wsdl:output message="tns:GetCelsiusResponse" name="GetCelsiusResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="TempPortSoap11" type="tns:TempPort">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="GetCelsius">
<soap:operation soapAction=""/>
<wsdl:input name="GetCelsiusRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="GetCelsiusResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="TempPortService">
<wsdl:port binding="tns:TempPortSoap11" name="TempPortSoap11">
<soap:address location="https://localhost:8443/ws"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Now build the project using gradle command – gradle clean build. Wait for downloading all the required files or jar APIs from the maven repository and finally you should see BUILD SUCCESSFUL message.
Next put the generated javaclient.jks (remember you generated this file during generating truststore) file under classpath directory src/main/resources. Put also the certificate.jks file (generated at the server side code) under classpath directory src/main/resources directory.
Now we need to create class for retrieving TrustManagerFactory and KeyManagerFactory and authenticate the client using certificate.
Create below class for retrieving TrustManagerFactory and KeyManagerFactory:
package com.jeejava.soap.config;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManagerFactory;
public class SoapClientConfig {
public KeyManagerFactory getKeyManagerFactory() {
InputStream inputStream = null;
KeyStore ts = null;
KeyManagerFactory keyManagerFactory = null;
try {
ts = KeyStore.getInstance("JKS");
inputStream = this.getClass().getClassLoader().getResourceAsStream("javaclient.jks");
ts.load(inputStream, "changeit".toCharArray());
keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(ts, "changeit".toCharArray());
} catch (NoSuchAlgorithmException | CertificateException | KeyStoreException | IOException
| UnrecoverableKeyException e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return keyManagerFactory;
}
public TrustManagerFactory getTrustManagerFactory() {
InputStream inputStream = null;
KeyStore ts = null;
TrustManagerFactory trustManagerFactory = null;
try {
ts = KeyStore.getInstance("JKS");
inputStream = this.getClass().getClassLoader().getResourceAsStream("certificate.jks");
ts.load(inputStream, "changeit".toCharArray());
trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(ts);
} catch (NoSuchAlgorithmException | CertificateException | KeyStoreException | IOException e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return trustManagerFactory;
}
}
Now create below client class to authenticate the client and convert the celsius temperature into fahrenheit temperature.
package com.jeejava.soap.client;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManagerFactory;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
import com.example.temperatureservice.GetCelsiusRequest;
import com.example.temperatureservice.GetCelsiusResponse;
import com.example.temperatureservice.TempPort;
import com.example.temperatureservice.TempPortService;
import com.jeejava.soap.config.SoapClientConfig;
public class SoapClient {
public static void main(String[] args) {
SoapClient soapClient = new SoapClient();
TempPortService tempPortService = new TempPortService();
TempPort tempPort = tempPortService.getTempPortSoap11();
soapClient.authenticateClient(tempPort);
GetCelsiusRequest celsiusRequest = new GetCelsiusRequest();
celsiusRequest.setCelcius(45);
GetCelsiusResponse response = tempPort.getCelsius(celsiusRequest);
System.out.println("The fahrenheit temperature " + response.getFahrenheit());
}
private void authenticateClient(TempPort tempPort) {
Client client = ClientProxy.getClient(tempPort);
HTTPConduit httpConduit = (HTTPConduit) client.getConduit();
SoapClientConfig soapClientConfig = new SoapClientConfig();
KeyManagerFactory keyManagerFactory = soapClientConfig.getKeyManagerFactory();
TrustManagerFactory trustManagerFactory = soapClientConfig.getTrustManagerFactory();
TLSClientParameters tslClientParameters = httpConduit.getTlsClientParameters();
if (tslClientParameters == null) {
tslClientParameters = new TLSClientParameters();
}
tslClientParameters.setTrustManagers(trustManagerFactory.getTrustManagers());
tslClientParameters.setKeyManagers(keyManagerFactory.getKeyManagers());
tslClientParameters.setDisableCNCheck(true);
httpConduit.setTlsClientParameters(tslClientParameters);
}
}
We have used apache cxf client API to authenticate using client certificate. Notice how we have set TrustManager and KeyManager.
We have also disable the CN check from localhost and ideally we should disable it. If you don’t check that the certificate’s CN doesn’t match the domain name then they can simply create their own certificate (and have it signed by a trusted CA so it looks valid), use it in place of yours, and perform a man in the middle attack. Also, you need to be checking that the certificate comes from a trusted CA. If you skip either of these checks then you are at risk of a MITM (man-in-the-middle) attack.
When you run the above class you should see the below output in the console:
The fahrenheit temperature 113.0
Note: we have used here apache cxf client to authenticate the client. Therefore you need to add below two dependencies into the client project’s build script.
dependencies {
compile("org.apache.cxf:cxf-rt-frontend-jaxws:2.7.7")
compile("org.apache.cxf:cxf-rt-transports-http:2.7.7")
}
Congratulations! You have successfully completed the example on SOAP over https with client certificate authentication.
Recommended reading:
Authentication example in JAX-WS webservice
SunCertPathBuilderException: unable to find valid certification path to requested target
Using SSL(Secure Socket Layer) in JAX-WS webservice
Source Code
You can download source code.
Thanks for reading.
The post SOAP over HTTPS with Client Certificate Authentication appeared first on JEE Tutorials.
Send Any File using SOAP Webservice
Introduction
This tutorial shows how we can send file using SOAP based webservice. The type of the file can be anything, i.e., text, image, pdf, MS doc etc. For this type of application we need to create two applications – one will work as a client application(which sends a file) and other one will work as a server application(which receives a file). So the server application will deploy the service whereas client application will consume the service. In server application we will have logic for what will be done with the file content after receiving the file. Using the client application we will upload the file and send through the SOAP service.
In this example both client and server applications are web based maven application. In client application we will upload the file using JSP, Servlet and send it to the server application which then saves the received file to the specific location on disk.
In this post we will use wsgen and wsimport through maven plugin to generate WSDL and stubs from WSDL, respectively.
Final Results
Home page

When no file selected for upload

When a file is selected and sent

Prerequisites
Eclipse Neon, Tomcat 8.5.39, JDK 1.8, maven 3.6.0
Example with Source Code
We will now look at the server and client applications how they get created.
Server Application
Creating Project
Create a maven based web application in Eclipse with the below group and artifact id:
Group Id: com.jeejava, Artifact Id: soap-send-file
The project structure will look similar to the below image:

Updating Build File
Update the default pom.xml file with the following content in order to include required dependencies for JAX-WS and wsgen command in jaxws maven plugin.
wsgen in jaxws maven plugin is used here to generate WSDL file for the SOAP webservice.
You can also use wsgen in jaxws command using cmd prompt if you do not want to use wsgen in jaxws maven plugin.
<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>com.jeejava</groupId>
<artifactId>soap-send-file</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.3.2</version>
</dependency>
</dependencies>
<build>
<finalName>soap-send-file</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>generate-wsdl</id>
<phase>process-classes</phase>
<goals>
<goal>wsgen</goal>
</goals>
<configuration>
<sei>com.jeejava.soap.service.impl.FileSendServiceImpl</sei>
<genWsdl>true</genWsdl>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Creating Service Endpoint Interface
Create endpoint interface with the below source code. In the below service endpoint interface we have only one method annotated with @WebMethod.
package com.jeejava.soap.service;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService
public interface FileSendService {
@WebMethod
String sendFile(byte[] fileContent, String fileName);
}
Creating Endpoint Implementation
Create endpoint implementation for the above endpoint service. This endpoint implementation class will implement the business logic for the sendFile() method.
package com.jeejava.soap.service.impl;
import javax.jws.WebService;
import com.jeejava.soap.service.FileSendService;
import com.jeejava.soap.service.util.FileUtils;
@WebService(endpointInterface = "com.jeejava.soap.service.FileSendService")
public class FileSendServiceImpl implements FileSendService {
@Override
public String sendFile(byte[] fileContent, String fileName) {
boolean response = FileUtils.saveFile(fileContent, fileName);
if (response) {
return "File successfully received and saved to disk!";
}
return "OOPs! some error occurred.";
}
}
Creating Utility Class
We have used a utility class in the above endpoint implementation class. So we will see the corresponding utility class that does some utility operations.
package com.jeejava.soap.service.util;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public final class FileUtils {
private FileUtils() {
}
public static boolean saveFile(byte[] fileContent, String fileName) {
OutputStream outputStream = null;
try {
File file = new File("C:/workspace" + File.separator + fileName);
outputStream = new FileOutputStream(file);
outputStream.write(fileContent);
return true;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return false;
}
}
Defining Endpoint Pattern
Create sun-jaxws.xml file with the below content and put it under WEB-INF directory. This file defines the endpoint pattern at which the WSDL file can be accessed.
<?xml version="1.0" encoding="UTF-8"?>
<endpoints
xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">
<endpoint name="SoapFileSend"
implementation="com.jeejava.soap.service.impl.FileSendServiceImpl"
url-pattern="/SoapFileSend" />
</endpoints>
Updating Deployment Descriptor
Modify web.xml file as below to have the servlet mapping using JAX-WS API. The JAX-WS servlet maps the endpoint URL pattern.
<?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_3_1.xsd"
version="3.1">
<display-name>soap-send-file</display-name>
<listener>
<listener-class>
com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
<servlet>
<servlet-name>SoapFileSend</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SoapFileSend</servlet-name>
<url-pattern>/SoapFileSend</url-pattern>
</servlet-mapping>
</web-app>
Enough coding! Let’s test our application on Tomcat server.
Building the Application
Build the application either from cmd prompt using mvn clean install or from the Eclipse option Run As -> Maven install.
The build should be successful with war and WSDL files generated.
Testing the Application
Now run the application by deploying on Tomcat server. Hit the URL http://<host>:<port>/<context path>/<URL pattern>?wsdl, i.e., http://localhost:8080/soap-send-file/SoapFileSend?wsdl. You will get the below wsdl file in the browser:

Client Application
Now we will see how we can consume the service and send file to the above application.
Creating Project
Create a maven based web project in Eclipse with the following group and artifact id.
Group Id: com.jeejava, Artifact Id: upload-file
The project structure may look similar to the below image:

Updating Build File
Update the pom.xml file to use required dependencies.
We have included servlet, jstl dependencies as we are working on web application for using servlet and jsp pages.
We have used wsimport in jaxws maven plugin to generate stubs from the WSDL file. We have used here URL for WSDL, if you want you may use WSDL local file as well. For that you have to uncomment the WSDL location with file name.
<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>com.jeejava</groupId>
<artifactId>upload-file</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<build>
<finalName>upload-file</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>generate-stubs</id>
<phase>generate-sources</phase>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<!-- using wsdl from an url -->
<wsdlUrls>
<wsdlLocation>http://localhost:8080/soap-send-file/SoapFileSend?wsdl</wsdlLocation>
</wsdlUrls>
<!-- or using wsdls file directory -->
<!-- <wsdlDirectory>src/wsdl</wsdlDirectory> -->
<!-- which wsdl file -->
<!-- <wsdlFiles> -->
<!-- <wsdlFile>myWSDL.wsdl</wsdlFile> -->
<!--</wsdlFiles> -->
<!-- Keep generated files -->
<keep>true</keep>
<!-- Package name -->
<packageName>com.jeejava.soap.stubs</packageName>
<!-- generated source files destination -->
<sourceDestDir>${basedir}/target/generated-classes</sourceDestDir>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Building the Application
Build the application either from cmd prompt using mvn clean install or from the Eclipse option Run As -> Maven install.
The stub should be generated and build should be successful.
Updating Deployment Descriptor
Modify the deployment descriptor file – web.xml as follows. We won’t put any entry for servlet in this file because we are using servlet 3 so using annotation is enough.
<?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_3_1.xsd"
version="3.1">
<display-name>Session Expiry Warning Message</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
Creating View File
Now create a view – index.jsp which will give user an opportunity to upload a file for sending using SOAP webservice.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Upload and Send File using SOAP Webservice - Servlet
Example</title>
</head>
<body>
<div style="width: 600px;">
<c:if test="${!empty error}">
<p style="color: red;">
<c:out value="${error}" />
</p>
</c:if>
<c:if test="${!empty success}">
<p style="color: green;">
<c:out value="${success}" />
</p>
</c:if>
<form method="post" action="Upload" enctype="multipart/form-data">
<fieldset>
<legend>Upload File</legend>
<p>
<label>Select File</label><br /> <input type="file" name="file"
id="file" />
</p>
<p>
<input type="submit" name="uploadFile" value="Upload File" />
</p>
</fieldset>
</form>
</div>
</body>
</html>
Creating Utility Class
Create FileUtil.java file which holds some utility methods.
package com.jeejava.upload.utils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import javax.servlet.http.Part;
public final class FileUtil {
private FileUtil() {
}
public static String getFilename(Part part) {
for (String cd : part.getHeader("content-disposition").split(";")) {
if (cd.trim().startsWith("filename")) {
String filename = cd.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
return filename.substring(filename.lastIndexOf('/') + 1).substring(filename.lastIndexOf('\\') + 1); // MSIE
// fix.
}
}
return null;
}
public static byte[] getFileContent(InputStream inputStream) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int reads = inputStream.read();
while (reads != -1) {
baos.write(reads);
reads = inputStream.read();
}
return baos.toByteArray();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
}
Creating Servlet
Create a servlet which will upload the file and send to the server application using SOAP service.
package com.jeejava.upload.servlet;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import com.jeejava.soap.stubs.FileSendService;
import com.jeejava.soap.stubs.FileSendServiceImplService;
import com.jeejava.upload.utils.FileUtil;
/**
* Servlet implementation class UploadServlet
*/
@WebServlet("/Upload")
@MultipartConfig
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public UploadServlet() {
super();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Part filePart = request.getPart("file");
String uploadSubmit = request.getParameter("uploadFile");
String fileName = FileUtil.getFilename(filePart);
if (uploadSubmit != null && fileName != null && fileName.length() > 0) {
InputStream inputStream = filePart.getInputStream();
byte[] fileContent = FileUtil.getFileContent(inputStream);
FileSendServiceImplService service = new FileSendServiceImplService();
FileSendService fileSendService = service.getFileSendServiceImplPort();
String resp = fileSendService.sendFile(fileContent, fileName);
if (!resp.contains("OOPs")) {
request.setAttribute("success", resp);
} else {
request.setAttribute("error", resp);
}
} else {
String msg = "OOPs! You must select a file to upload.";
request.setAttribute("error", msg);
}
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/index.jsp");
requestDispatcher.forward(request, response);
}
}
Testing the Application
Now run the application by deploying on Tomcat server. Hit the URL http://localhost:8080/upload-file/ to upload file and see the results as you have seen in Final Results section.
Note: Please run the server application first in order to receive and save the file onto disk.
Source Code
You can download source code.
Thanks for reading.
The post Send Any File using SOAP Webservice appeared first on JEE Tutorials.
Generating stubs from multiple WSDL files using Maven or Gradle
This tutorial may be useful when you want to generate stubs from multiple WSDL files using maven or gradle plugin.
Use below maven based plugin to generate stubs
... <build> <plugins> <plugin> <groupId>org.apache.cxf</groupId> <artifactId>cxf-codegen-plugin</artifactId> <version>3.1.10</version> <executions> <execution> <id>generate-sources</id> <phase>generate-sources</phase> <configuration> <sourceRoot>${basedir}/src/main/java</sourceRoot> <wsdlOptions> <wsdlOption> <wsdl>${basedir}/src/main/resources/wsdl/<wsdl1>.wsdl</wsdl> <!-- if you want to use URL --> <!-- <wsdl>http://<host>:<port>/<name1>.wsdl</wsdl> --> </wsdlOption> <wsdlOption> <wsdl>${basedir}/src/main/resources/wsdl/<wsdl2>.wsdl</wsdl> <!-- if you want to use URL --> <!-- <wsdl>http://<host>:<port>/<name2>.wsdl</wsdl> --> </wsdlOption> </wsdlOptions> </configuration> <goals> <goal>wsdl2java</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
Use below gradle based plugin to generate stubs
buildscript { repositories { mavenCentral() } dependencies { classpath 'no.nils:wsdl2java:0.10' } } apply plugin: 'java' apply plugin: 'no.nils.wsdl2java' wsdl2javaExt { cxfVersion = "3.1.10" } wsdl2java{ generatedWsdlDir = file("${projectDir}/src/main/service") //java source classes will be generated wsdlDir=file("${projectDir}/src/main/resources/wsdl/") //wsdl directory wsdlsToGenerate = [ [file("${projectDir}/src/main/resources/wsdl/wsdl1.wsdl")], //wsdl1 [file("${projectDir}/src/main/resources/wsdl/wsdl2.wsdl")], //wsdl2 [file("${projectDir}/src/main/resources/wsdl/wsdl3.wsdl")] //wsdl3 ] } compileJava.dependsOn wsdl2java ...
Thanks for reading.
The post Generating stubs from multiple WSDL files using Maven or Gradle appeared first on JEE Tutorials.