JAX-WS Hello World Example – Document Style
In this tutorial, we show you how to use JAX-WS to create a SOAP-based web service (document style) endpoint. Compare with RPC style, it need some extra efforts to get it works.
Directory structure of this example
JAX-WS Web Service End Point
Here are the steps to create a document style web service in JAX-WS.
1. Create a Web Service Endpoint Interface
Actually, annotated with @SOAPBinding
is optional, because the default style is document.
File : HelloWorld.java
package com.mkyong.ws;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
//Service Endpoint Interface
@WebService
@SOAPBinding(style = Style.DOCUMENT, use=Use.LITERAL) //optional
public interface HelloWorld{
@WebMethod String getHelloWorldAsString(String name);
}
In JAX-WS development, convert from “RPC style” to “Document style” is very easy, just change the
@SOAPBinding
style option.
2. Create a Web Service Endpoint Implementation
File : HelloWorldImpl.java
package com.mkyong.ws;
import javax.jws.WebService;
//Service Implementation
@WebService(endpointInterface = "com.mkyong.ws.HelloWorld")
public class HelloWorldImpl implements HelloWorld{
@Override
public String getHelloWorldAsString(String name) {
return "Hello World JAX-WS " + name;
}
}
3. Create a Endpoint Publisher.
File : HelloWorldPublisher.java
package com.mkyong.endpoint;
import javax.xml.ws.Endpoint;
import com.mkyong.ws.HelloWorldImpl;
//Endpoint publisher
public class HelloWorldPublisher{
public static void main(String[] args) {
Endpoint.publish("http://localhost:9999/ws/hello", new HelloWorldImpl());
}
}
Wait, when you run the end point publisher, you will hits following error message :
Wrapper class com.mkyong.ws.jaxws.GetHelloWorldAsString is not found.
Have you run APT to generate them?
See this article. You need to use “wsgen” tool to generate necessary JAX-WS portable artifacts. Let move to next step.
4. wsgen command
Document style requires extra classes to run, you can use “wsgen” to generate all necessary Java artifacts (mapping classes, wsdl or xsd schema). The “wsgen” command is required to read a service endpoint implementation class :
wsgen -keep -cp . com.mkyong.ws.HelloWorldImpl
It will generate two classes, copy it to your “package.jaxws” folder.
File : GetHelloWorldAsString.java
package com.mkyong.ws.jaxws;
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 = "getHelloWorldAsString", namespace = "http://ws.mkyong.com/")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getHelloWorldAsString", namespace = "http://ws.mkyong.com/")
public class GetHelloWorldAsString {
@XmlElement(name = "arg0", namespace = "")
private String arg0;
/**
*
* @return
* returns String
*/
public String getArg0() {
return this.arg0;
}
/**
*
* @param arg0
* the value for the arg0 property
*/
public void setArg0(String arg0) {
this.arg0 = arg0;
}
}
File : GetHelloWorldAsStringResponse.java
package com.mkyong.ws.jaxws;
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 = "getHelloWorldAsStringResponse", namespace = "http://ws.mkyong.com/")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getHelloWorldAsStringResponse", namespace = "http://ws.mkyong.com/")
public class GetHelloWorldAsStringResponse {
@XmlElement(name = "return", namespace = "")
private String _return;
/**
*
* @return
* returns String
*/
public String getReturn() {
return this._return;
}
/**
*
* @param _return
* the value for the _return property
*/
public void setReturn(String _return) {
this._return = _return;
}
}
The “wsgen” tool is available in the “JDK_Path\bin\” folder. For detail, please read this JAX-WS : wsgen tool example article.
5. Done
Done, publish it and test it via URL : http://localhost:9999/ws/hello?wsdl.
Web Service Client
Create a web service client to access your published service.
File : HelloWorldClient.java
package com.mkyong.client;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import com.mkyong.ws.HelloWorld;
public class HelloWorldClient{
public static void main(String[] args) throws Exception {
URL url = new URL("http://localhost:9999/ws/hello?wsdl");
QName qname = new QName("http://ws.mkyong.com/", "HelloWorldImplService");
Service service = Service.create(url, qname);
HelloWorld hello = service.getPort(HelloWorld.class);
System.out.println(hello.getHelloWorldAsString("mkyong"));
}
}
Output
Hello World JAX-WS mkyong
Tracing SOAP Traffic
From top to bottom, showing how SOAP envelope flows between client and server in this document style web service.
1. Request a WSDL file
First, client send a wsdl request to service endpoint :
Client send request :
GET /ws/hello?wsdl HTTP/1.1
User-Agent: Java/1.6.0_13
Host: localhost:9999
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Server send response :
HTTP/1.1 200 OK
Transfer-encoding: chunked
Content-type: text/xml;charset=utf-8
<?xml version="1.0" encoding="UTF-8"?>
<!-- Published by JAX-WS RI at http://jax-ws.dev.java.net.
RI's version is JAX-WS RI 2.1.1 in JDK 6. -->
<!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net.
RI's version is JAX-WS RI 2.1.1 in JDK 6. -->
<definitions
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://ws.mkyong.com/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://ws.mkyong.com/"
name="HelloWorldImplService">
<types>
<xsd:schema>
<xsd:import namespace="http://ws.mkyong.com/"
schemaLocation="http://localhost:9999/ws/hello?xsd=1"></xsd:import>
</xsd:schema>
</types>
<message name="getHelloWorldAsString">
<part name="parameters" element="tns:getHelloWorldAsString"></part>
</message>
<message name="getHelloWorldAsStringResponse">
<part name="parameters" element="tns:getHelloWorldAsStringResponse"></part>
</message>
<portType name="HelloWorld">
<operation name="getHelloWorldAsString">
<input message="tns:getHelloWorldAsString"></input>
<output message="tns:getHelloWorldAsStringResponse"></output>
</operation>
</portType>
<binding name="HelloWorldImplPortBinding" type="tns:HelloWorld">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document">
</soap:binding>
<operation name="getHelloWorldAsString">
<soap:operation soapAction=""></soap:operation>
<input>
<soap:body use="literal"></soap:body>
</input>
<output>
<soap:body use="literal"></soap:body>
</output>
</operation>
</binding>
<service name="HelloWorldImplService">
<port name="HelloWorldImplPort" binding="tns:HelloWorldImplPortBinding">
<soap:address location="http://localhost:9999/ws/hello"></soap:address>
</port>
</service>
</definitions>
2. getHelloWorldAsString(String name)
A second call, client put method invoke request in SOAP envelope and send it to service endpoint. At the service endpoint, call the requested method and put the result in a SOAP envelope and send it back to client.
Client send request :
POST /ws/hello HTTP/1.1
SOAPAction: ""
Accept: text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Content-Type: text/xml; charset=utf-8
User-Agent: Java/1.6.0_13
Host: localhost:9999
Connection: keep-alive
Content-Length: 224
<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getHelloWorldAsString xmlns:ns2="http://ws.mkyong.com/">
<arg0>mkyong</arg0>
</ns2:getHelloWorldAsString>
</S:Body>
</S:Envelope>
Server send response :
HTTP/1.1 200 OK
Transfer-encoding: chunked
Content-type: text/xml; charset=utf-8
<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getHelloWorldAsStringResponse xmlns:ns2="http://ws.mkyong.com/">
<return>Hello World JAX-WS mkyong</return>
</ns2:getHelloWorldAsStringResponse>
</S:Body>
</S:Envelope>
Hi Friends, One doubt. i sawthe JAX WS spec. From that they mentioned, implements of JAX WS are Metro Project in GlassFish
Apache CXF
Apache Axis2
JBossWS in JBoss
IBM WebSphere Jax-Ws in WebSphere
Oracle Weblogic.
In this example which implementation have been used. Please advice.
Hi,
I am trying to send XML Document to Web Service built on C# Dot Net how to do it?
Hi,
I am newbie in this topic and I want to ask something. I have Java SE (Kepler). What stuff do I need to run code. Have I got Tomcat, can I use Wamp server . At last, how can I run “wsgen -keep -cp . com.mkyong.ws.HelloWorldImpl” and where I should run this code.(path?) ?
Thank you in advance.
Hi All,
I have the same concern with Asbek, everyone can give me explaination about this?
“com.mkyong.ws.HelloWorld;
HelloWorld class is serverside code.How can you import it in client side?”
Regards,
saigonvangem
You are right you cannot import an interface located on the service in your client side code, but you have an the same interface on the client side it would work fine. The author forgot to mention in this tutorial about using wsimport to generate client side code using wsdl file from the server. The same step is explained in an earlier tutorial featuring RPC document type of RPC type which just one tutorial above this one in the main page.
Hi kong,
This example is really good for understanding/executing the example. I think your example is best way to start jax ws webservice. i have below comments
i used below commands to run the example. plz make a note and change if required
wsgen -cp bin -d bin com.mykong.ws.HelloWorldImpl
wsgen -s src -cp bin -d bin com.mykong.ws.HelloWorldImpl
hi all,
I have a question: How to remove “ns…” and replace “return” in response xml:
– “ns2:ReceiveMOResponse” i want to xml format response: “ReceiveMOResponse”
– “return” to “ReceiveMOResult”
How to handle multiPart in wsdl. if wsdl file has more then one part in the message. For example:
How to handle this as axis2 in supporting multiparts in document/litral style.
Please help me here.
Below is the example:
————————————
what is this, client, server, publisher, xml, SOAP and this is a solution for busines. I do not need java for java , i need java for busines. So much classes, text, and at the end I belive does not work … no thank*s
Hi,
I’m net to JAX-WS can you tell me how can I remove chunked from Transfer-Encoding from response?
Hi…
I am new in this topic and i want to ask somethig. I have ready made wsdl web service i want to use this in my project. In this web service i want to pass some parameters. How can I do this?
can you share a sample code for jax-ws + ejb3 and jax-rs+ejb3?
hi everybody
i not found solution to my problem. i use jax ws maven plugin to generate the wsdl file for my web services.
after a successfully building i not found the wsdl file in any folder in my project. but i found the .class
any suggestion or solution
Good Article,
I have a Question here or i can say i am having the problem which i am trying to solve on the same way.
I am referring the
“Server send response” Section
And about the following line
—
—
I do not want the request to be in another location, i want to embed it in the same wsdl file, is there any way for this.
If i use way which is configured in spirng config.. i am getting it embed in wsdl, when i use annotations it is creating it another location.
Let me know if i missed anything / need more info.
Hello Mkyong,
First of all I liked your tutorials really. It is very descriptive. I tried this one . I can publish the web service and run the client. It works perfect. My web service code and client code is part of a larger project. When I deploy my war file on Tomcat I get error which is below. My Tomcat version is : 7.0.40 . I ran tomcat as a stnadalone application by startup.bat file (as an administrator). The deployment problem is caused because of web service codes because when i remove them I can deploy rest of the application. I will be very happy if you can help me. I have to finish this (masters) project in at most 2 days.
Ferda
SEVERE: WSSERVLET11: failed to parse runtime descriptor: com.sun.xml.ws.util.Ser
viceConfigurationError: com.sun.xml.ws.policy.jaxws.spi.PolicyFeatureConfigurato
r: Provider com.sun.xml.ws.addressing.policy.AddressingFeatureConfigurator is sp
ecified in jar:file:/C:/Program%20Files/Apache/apache-tomcat-7.0.40/webapps/ROOT
/WEB-INF/lib/webservices-rt.jar!/META-INF/services/com.sun.xml.ws.policy.jaxws.s
pi.PolicyFeatureConfiguratorbut could not be instantiated: java.lang.ClassCastEx
ception: Cannot cast com.sun.xml.ws.addressing.policy.AddressingFeatureConfigura
tor to com.sun.xml.ws.policy.jaxws.spi.PolicyFeatureConfigurator
com.sun.xml.ws.util.ServiceConfigurationError: com.sun.xml.ws.policy.jaxws.spi.P
olicyFeatureConfigurator: Provider com.sun.xml.ws.addressing.policy.AddressingFe
atureConfigurator is specified in jar:file:/C:/Program%20Files/Apache/apache-tom
cat-7.0.40/webapps/ROOT/WEB-INF/lib/webservices-rt.jar!/META-INF/services/com.su
n.xml.ws.policy.jaxws.spi.PolicyFeatureConfiguratorbut could not be instantiated
: java.lang.ClassCastException: Cannot cast com.sun.xml.ws.addressing.policy.Add
ressingFeatureConfigurator to com.sun.xml.ws.policy.jaxws.spi.PolicyFeatureConfi
gurator
at com.sun.xml.ws.util.ServiceFinder.fail(ServiceFinder.java:258)
at com.sun.xml.ws.util.ServiceFinder.access$300(ServiceFinder.java:151)
at com.sun.xml.ws.util.ServiceFinder$LazyIterator.next(ServiceFinder.jav
a:465)
at com.sun.xml.ws.util.ServiceFinder$CompositeIterator.next(ServiceFinde
r.java:402)
at com.sun.xml.ws.policy.jaxws.PolicyUtil.addServiceProviders(PolicyUtil
.java:97)
at com.sun.xml.ws.policy.jaxws.PolicyUtil.(PolicyUtil.java:83)
at com.sun.xml.ws.policy.jaxws.PolicyWSDLGeneratorExtension.loadConfigur
ators(PolicyWSDLGeneratorExtension.java:476)
at com.sun.xml.ws.policy.jaxws.PolicyWSDLGeneratorExtension.start(Policy
WSDLGeneratorExtension.java:124)
at com.sun.xml.ws.wsdl.writer.WSDLGeneratorExtensionFacade.start(WSDLGen
eratorExtensionFacade.java:71)
at com.sun.xml.ws.wsdl.writer.WSDLGenerator.generateDocument(WSDLGenerat
or.java:407)
at com.sun.xml.ws.wsdl.writer.WSDLGenerator.doGeneration(WSDLGenerator.j
ava:330)
at com.sun.xml.ws.db.DatabindingImpl.generateWSDL(DatabindingImpl.java:2
30)
at com.sun.xml.ws.server.EndpointFactory.generateWSDL(EndpointFactory.ja
va:553)
at com.sun.xml.ws.server.EndpointFactory.create(EndpointFactory.java:278
)
at com.sun.xml.ws.server.EndpointFactory.createEndpoint(EndpointFactory.
java:147)
at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:574)
at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:557)
at com.sun.xml.ws.transport.http.DeploymentDescriptorParser.parseAdapter
s(DeploymentDescriptorParser.java:260)
at com.sun.xml.ws.transport.http.DeploymentDescriptorParser.parse(Deploy
mentDescriptorParser.java:152)
at com.sun.xml.ws.transport.http.servlet.WSServletContextListener.parseA
daptersAndCreateDelegate(WSServletContextListener.java:131)
at com.sun.xml.ws.transport.http.servlet.WSServletContainerInitializer.o
nStartup(WSServletContainerInitializer.java:65)
at org.apache.catalina.core.StandardContext.startInternal(StandardContex
Hello Again my problem is solved when i add metro jars https://metro.java.net/2.0/ under webinf/lib .
Putting same files under tomcat/lib did not solve the problem. Thank you for your time…
Ferda
So clearly explanation. Thank you very much
best regards,
FurmanS
How we can generates the server code form a WSDL file like other web service framework
JAX-WS provides any tool for this?.
Hi,
I can see the namespace defined at element level. Can this be moved to envelope level in jax-ws?
I am new to web sevice, can you clarify what ‘s difference between RPC and Document style. thanks in advance.
Please read http://oracled.wordpress.com/2008/09/12/rpc-style-vs-document-style-web-service/
What is this publisher class? I’d like to know how to deploy this service onto a Tomcat server.
Hi, How is this is a Document style messaging? The SOAP-BODY has method name as the first element. Isn’t this still going the RPC way ?
hi
i’m trying to consume a web service doclit type but it’s published under https protocol and the clients that i’m using are not able to cosume it, what kind of extra work need to be done in order for this to work
thanks
Hey great article, but I have absolutely no experience with web services and I don’t know how to publish the service after I create. You say simply “now publish and test it” but how \_(o.O)_/
Hi
I have looked at many of your (Mkyoung) web pages recently. You have done an excellent job in posting very useful information.
I ran above example, I am not getting soap envelope back from server response. it is just an xml. Can you please let me know how can I get it ?
Thanks
K
You should see in tracing soap traffic point above or you can test with soapUI to see envelope request and response easily.
I’m confused on step 5. How do I publish to http://localhost:9999/ws/hello?wsdl? Also, am I suppose to have a WSDL in my project somewhere? I don’t see where a WSDL is created in the tutorial.
I’m using Tomcat 7 if that helps answer my question.
Thanks
To publish I just had to run HelloWorldPublisher…duh
So I can see the WSDL at http://localhost:8080/ws/hello?wsdl after running HelloWorldPublisher. But when I run HelloWorldClient I get the error bellow. Any idea what I can be doing wrong?
in your GetHelloWorldAsString.java and GetHelloWorldAsStringRepsonse.java files, change the add “/” to the namespace.
So it would be
Hi,
In the document style web service as u mentioned we have to genereate WS artifacts but i am able to run web service without genereting it with wsgen.
But u mentioned that it will give error msg as
“Wrapper class com.mkyong.ws.jaxws.GetHelloWorldAsString is not found.
Have you run APT to generate them?”
Kindly explain it
Thanks
Apparently the JDK(1.6.0_13 and below) was not using right version of required JARS.
Its fixed in the new JDK’s.
I had the same question, so I did a experiment. Here is my observation,
With JDK 6 (more precisely 1.6.0_45), I encountered the error (but my error says INFO: Dynamically creating request wrapper Class com.mkyong.ws.jaxws.GetHelloWorldAsString on ). And after running wsgen, the publisher just worked fine.
With JDK 7, I was able to publish the service with no need to run wsgen.
Dino,
“INFO: Dynamically creating request wrapper Class com.mkyong.ws.jaxws.GetHelloWorldAsString on” is not a ERROR. Its a message printed out. I guess this question was never answered.
Even for me it works and the generated wsld also correct as per the document style.. I don’t know, I believe that is not required with standalone.
I am seeing the same thing. Can you explain why? Also can you talk to the difference between running wsgen as you have shown here vs running wsimport on the wsdl for generating classes on the client side as covered here: http://java.dzone.com/articles/jax-ws-hello-world.
Appreciate all your doing here! thanks!
Same with me.I am able to run the web service without using wsgen.I just changed the style to DOCUMENT and it is running.
Hi, thank you for always providing very informative and easy to read tutorial.
I have a dumb question about web services in general if you don’t mind.
In this example, you created web service end point as standalone.
public static void main(String[] args) {
Endpoint.publish(“http://localhost:9999/ws/hello”, new HelloWorldImpl());
}
But I know, I can also generate the web services using eclipse which then will run as web app on server like tomcat.
What is the difference between these two? I mean is there any standard way of doing it or preferred way? any pro and con?
Any comment will be very much appreciated. Thanks
Standalone is just for demonstrate purpose, rarely use in production environment. Often times, you just run web service along with your web application.
Hello Mkyoung,
In this case if I want to run the previous example as web app what should I do?
Many thanks in advance.
Hi.
Thank you for very informative and compact tutorials.
In step 4. WSGEN, instead of copying, one can use an “-s ” argument in conjunction with “-keep” to specify where to place generated source files.
For instance:
so the generated source files will end up in /jaxws folder.
Hi Levan, thanks for your additional inputs.
Sorry, in the above comment some part was for some reason truncated.
After the “-s” argument should follow the path to desired directory:
wsgen -keep -s path/to/some/directory -cp . com.mkyong.ws.HelloWorldImpl
Then the generated source files will end up in “path/to/some/directory/jaxws” folder.
Please mention the difference between RPC and document style of Webservices
Hi,
com.mkyong.ws.HelloWorld;
HelloWorld class is serverside code.How can you import it in client side?
Regards,
Aslan
Hi All,
I have the same concern with Asbek, everyone can give me explaination about this?
“com.mkyong.ws.HelloWorld;
HelloWorld class is serverside code.How can you import it in client side?”
Regards,
saigonvangem
test