Understanding JAX-WS wsgen with example
What is wsgen?
wsgen is a command line tool provided by JAX-WS to generate all the artifacts required for web service deployment and invocation.
In simple words, wsgen takes web service implementation class as an input and generates all the required artifacts for web service deployment.
It’s provided as part of Java 1.6 and it is available under JDK_PATH/bin folder
When to use wsgen?
We should use it in the below 2 scenarios
1) Whenever we want to generate web service artifacts (java files) for web service deployment
This is mostly required for Document style web service development
2) Whenever we want to provide Web service consuming details to web service consumers,In this case its required to generate WSDL and XSD files.
As WSDL file is the most important file for the web service consumers to understand and invoke the web service.
Consumers will use this WSDL file to develop the client and consume the published web service.
wsgen command syntax
- wsgen -keep -cp . webServiceImplClass
wsgen -keep -cp . webServiceImplClass
-keep option specifies that it has to keep the generated files.
-cp specifies the classpath
. Indicates current directory
webServiceImplClass – it’s the web service implementation class
Requirement:
Create a web service to find whether given number is prime or not and develop a client which consumes it.
Let’s implement this requirement with below steps
Step 1
Create a new Java maven project in eclipse
Step 2
Create a service implementation class
- package com.kb.ws;
- import javax.jws.WebMethod;
- import javax.jws.WebService;
- @WebService
- public class PrimeNumberServiceImpl{
- @WebMethod
- public boolean isPrimeNumber(int number) {
- for(int i=2;i<=number/2;i++){
- if(number % i == 0)
- return false;
- }
- return true;
- }
- }
package com.kb.ws; import javax.jws.WebMethod; import javax.jws.WebService; @WebService public class PrimeNumberServiceImpl{ @WebMethod public boolean isPrimeNumber(int number) { for(int i=2;i<=number/2;i++){ if(number % i == 0) return false; } return true; } }
Since we are directly adding @webMethod annotation to the methods in the implementation class, we don’t need to use interface for the same.
Step 3
Generate web service artifacts(java files)
We will use wsgen command to generate the required artifacts by using above implementation class (PrimeNumberServiceImpl.java)
Open command prompt, go to the below path
D:\workspace\WebServices\WsgenJaxws\target\classes
Issue the following command:
- wsgen -keep -cp . com.kb.ws.PrimeNumberServiceImpl
wsgen -keep -cp . com.kb.ws.PrimeNumberServiceImpl
Note
The classpath specified via -cp should point to the directory that contains the compiled classes, typically the target/classes folder in maven project and bin folder in java project.
Now check the below files are generated in the same path from where we issued the command
Generated source files are as below
IsPrimeNumber.java
- package com.kb.ws.client;
- import javax.xml.bind.annotation.XmlAccessType;
- import javax.xml.bind.annotation.XmlAccessorType;
- import javax.xml.bind.annotation.XmlElement;
- import javax.xml.bind.annotation.XmlRootElement;
- import javax.xml.bind.annotation.XmlType;
- @XmlRootElement(name = "isPrimeNumber", namespace = "http://ws.kb.com/")
- @XmlAccessorType(XmlAccessType.FIELD)
- @XmlType(name = "isPrimeNumber", namespace = "http://ws.kb.com/")
- public class IsPrimeNumber {
- @XmlElement(name = "arg0", namespace = "")
- private int arg0;
- /**
- *
- * @return
- * returns int
- */
- public int getArg0() {
- return this.arg0;
- }
- /**
- *
- * @param arg0
- * the value for the arg0 property
- */
- public void setArg0(int arg0) {
- this.arg0 = arg0;
- }
- }
package com.kb.ws.client; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; @XmlRootElement(name = "isPrimeNumber", namespace = "http://ws.kb.com/") @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "isPrimeNumber", namespace = "http://ws.kb.com/") public class IsPrimeNumber { @XmlElement(name = "arg0", namespace = "") private int arg0; /** * * @return * returns int */ public int getArg0() { return this.arg0; } /** * * @param arg0 * the value for the arg0 property */ public void setArg0(int arg0) { this.arg0 = arg0; } }
IsPrimeNumberResponse.java
- package com.kb.ws.client;
- import javax.xml.bind.annotation.XmlAccessType;
- import javax.xml.bind.annotation.XmlAccessorType;
- import javax.xml.bind.annotation.XmlElement;
- import javax.xml.bind.annotation.XmlRootElement;
- import javax.xml.bind.annotation.XmlType;
- @XmlRootElement(name = "isPrimeNumberResponse", namespace = "http://ws.kb.com/")
- @XmlAccessorType(XmlAccessType.FIELD)
- @XmlType(name = "isPrimeNumberResponse", namespace = "http://ws.kb.com/")
- public class IsPrimeNumberResponse {
- @XmlElement(name = "return", namespace = "")
- private boolean _return;
- /**
- *
- * @return
- * returns boolean
- */
- public boolean isReturn() {
- return this._return;
- }
- /**
- *
- * @param _return
- * the value for the _return property
- */
- public void setReturn(boolean _return) {
- this._return = _return;
- }
- }
package com.kb.ws.client; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; @XmlRootElement(name = "isPrimeNumberResponse", namespace = "http://ws.kb.com/") @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "isPrimeNumberResponse", namespace = "http://ws.kb.com/") public class IsPrimeNumberResponse { @XmlElement(name = "return", namespace = "") private boolean _return; /** * * @return * returns boolean */ public boolean isReturn() { return this._return; } /** * * @param _return * the value for the _return property */ public void setReturn(boolean _return) { this._return = _return; } }
Step 4
Copy these files to our project and adjust the package names in the java files accordingly
Step 5
Now generate WSDL file using wsgen command
We just need to add –wsdl option to wsgen command to generate the WSDL and XSD files
Issue the below command from command window
- wsgen -keep -cp . com.kb.ws.PrimeNumberServiceImpl –wsdl
wsgen -keep -cp . com.kb.ws.PrimeNumberServiceImpl –wsdl
Step 6
Check the generated wsdl and xsd files
Generated wsdl file
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <!-- Generated by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. -->
- <definitions targetNamespace="http://ws.kb.com/" name="PrimeNumberServiceImplService" 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://ws.kb.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://ws.kb.com/" schemaLocation="PrimeNumberServiceImplService_schema1.xsd"/>
- </xsd:schema>
- </types>
- <message name="isPrimeNumber">
- <part name="parameters" element="tns:isPrimeNumber"/>
- </message>
- <message name="isPrimeNumberResponse">
- <part name="parameters" element="tns:isPrimeNumberResponse"/>
- </message>
- <portType name="PrimeNumberServiceImpl">
- <operation name="isPrimeNumber">
- <input wsam:Action="http://ws.kb.com/PrimeNumberServiceImpl/isPrimeNumberRequest" message="tns:isPrimeNumber"/>
- <output wsam:Action="http://ws.kb.com/PrimeNumberServiceImpl/isPrimeNumberResponse" message="tns:isPrimeNumberResponse"/>
- </operation>
- </portType>
- <binding name="PrimeNumberServiceImplPortBinding" type="tns:PrimeNumberServiceImpl">
- <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
- <operation name="isPrimeNumber">
- <soap:operation soapAction=""/>
- <input>
- <soap:body use="literal"/>
- </input>
- <output>
- <soap:body use="literal"/>
- </output>
- </operation>
- </binding>
- <service name="PrimeNumberServiceImplService">
- <port name="PrimeNumberServiceImplPort" binding="tns:PrimeNumberServiceImplPortBinding">
- <soap:address location="REPLACE_WITH_ACTUAL_URL"/>
- </port>
- </service>
- </definitions>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!-- Generated by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. --> <definitions targetNamespace="http://ws.kb.com/" name="PrimeNumberServiceImplService" 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://ws.kb.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://ws.kb.com/" schemaLocation="PrimeNumberServiceImplService_schema1.xsd"/> </xsd:schema> </types> <message name="isPrimeNumber"> <part name="parameters" element="tns:isPrimeNumber"/> </message> <message name="isPrimeNumberResponse"> <part name="parameters" element="tns:isPrimeNumberResponse"/> </message> <portType name="PrimeNumberServiceImpl"> <operation name="isPrimeNumber"> <input wsam:Action="http://ws.kb.com/PrimeNumberServiceImpl/isPrimeNumberRequest" message="tns:isPrimeNumber"/> <output wsam:Action="http://ws.kb.com/PrimeNumberServiceImpl/isPrimeNumberResponse" message="tns:isPrimeNumberResponse"/> </operation> </portType> <binding name="PrimeNumberServiceImplPortBinding" type="tns:PrimeNumberServiceImpl"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <operation name="isPrimeNumber"> <soap:operation soapAction=""/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> </operation> </binding> <service name="PrimeNumberServiceImplService"> <port name="PrimeNumberServiceImplPort" binding="tns:PrimeNumberServiceImplPortBinding"> <soap:address location="REPLACE_WITH_ACTUAL_URL"/> </port> </service> </definitions>
Generated xsd file
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <xs:schema version="1.0" targetNamespace="http://ws.kb.com/" xmlns:tns="http://ws.kb.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
- <xs:element name="isPrimeNumber" type="tns:isPrimeNumber"/>
- <xs:element name="isPrimeNumberResponse" type="tns:isPrimeNumberResponse"/>
- <xs:complexType name="isPrimeNumber">
- <xs:sequence>
- <xs:element name="arg0" type="xs:int"/>
- </xs:sequence>
- </xs:complexType>
- <xs:complexType name="isPrimeNumberResponse">
- <xs:sequence>
- <xs:element name="return" type="xs:boolean"/>
- </xs:sequence>
- </xs:complexType>
- </xs:schema>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <xs:schema version="1.0" targetNamespace="http://ws.kb.com/" xmlns:tns="http://ws.kb.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="isPrimeNumber" type="tns:isPrimeNumber"/> <xs:element name="isPrimeNumberResponse" type="tns:isPrimeNumberResponse"/> <xs:complexType name="isPrimeNumber"> <xs:sequence> <xs:element name="arg0" type="xs:int"/> </xs:sequence> </xs:complexType> <xs:complexType name="isPrimeNumberResponse"> <xs:sequence> <xs:element name="return" type="xs:boolean"/> </xs:sequence> </xs:complexType> </xs:schema>
Step 7
Create the web service Publisher class
- package com.kb.endpoint;
- import javax.xml.ws.Endpoint;
- import com.kb.ws.PrimeNumberServiceImpl;
- public class PrimeNumberPublisher {
- public static void main(String[] args) {
- Endpoint endpoint = Endpoint.create(new PrimeNumberServiceImpl());
- endpoint.publish("http://localhost:8888/ws/primeNumber");
- //Endpoint.publish("http://localhost:8888/ws/primeNumber", new PrimeNumberServiceImpl());
- }
- }
package com.kb.endpoint; import javax.xml.ws.Endpoint; import com.kb.ws.PrimeNumberServiceImpl; public class PrimeNumberPublisher { public static void main(String[] args) { Endpoint endpoint = Endpoint.create(new PrimeNumberServiceImpl()); endpoint.publish("http://localhost:8888/ws/primeNumber"); //Endpoint.publish("http://localhost:8888/ws/primeNumber", new PrimeNumberServiceImpl()); } }
That's all, we are done,Run the above class to publish the web service and provide WSDL file to web service consumers
You did not clarify enough what the various paths, especially classpath, are needed for and what files wsgen operates on: the source (.java) or generated class (.class) files. There should be a step called “compile the java source into corresponding ‘.class’ files which will be used by wsgen as inputs”, or something like that.
Excelente, me fue de mucha ayuda. Gracias!
Gracias, lectura feliz !!
Hi,
I am unable to understand why JAX-B artifacts are needed for Web service deployment (your use case 1).
Thanks