JAX-WS Hello World Example – RPC Style
JAX-WS is bundled with JDK 1.6, which makes Java web service development easier to develop. This tutorial shows you how to do the following tasks:
- Create a SOAP-based RPC style web service endpoint by using JAX-WS.
- Create a Java web service client manually.
- Create a Java web service client via wsimport tool.
- Create a Ruby web service client.
You will be surprise of how simple it is to develop a RPC style web service in JAX-WS.
In general words, “web service endpoint” is a service which published outside for user to access; where “web service client” is the party who access the published service.
JAX-WS Web Service End Point
The following steps showing how to use JAX-WS to create a RPC style web service endpoint.
1. Create a Web Service Endpoint Interface
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.RPC) public interface HelloWorld{ @WebMethod String getHelloWorldAsString(String name); }
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()); } }
Run the endpoint publisher, and your “hello world web service” is deployed in URL “http://localhost:9999/ws/hello“.
4. Test It
You can test the deployed web service by accessing the generated WSDL (Web Service Definition Language) document via this URL “http://localhost:9999/ws/hello?wsdl” .
Web Service Clients
Ok, web service is deployed properly, now let’s see how to create web service client to access to the published service.
1. Java Web Service Client
Without tool, you can create a Java web service client like this :
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"); //1st argument service URI, refer to wsdl document above //2nd argument is service name, refer to wsdl document above 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
2. Java Web Service Client via wsimport tool
Alternative, you can use “wsimport” tool to parse the published wsdl file, and generate necessary client files (stub) to access the published web service.
This wsimport tool is bundle with the JDK, you can find it at “JDK_PATH/bin” folder.
Issue “wsimport” command.
wsimport -keep http://localhost:9999/ws/hello?wsdl
It will generate necessary client files, which is depends on the provided wsdl file. In this case, it will generate one interface and one service implementation file.
File : HelloWorld.java
package com.mkyong.ws; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; /** * This class was generated by the JAX-WS RI. * JAX-WS RI 2.1.1 in JDK 6 * Generated source version: 2.1 * */ @WebService(name = "HelloWorld", targetNamespace = "http://ws.mkyong.com/") @SOAPBinding(style = SOAPBinding.Style.RPC) public interface HelloWorld { /** * * @param arg0 * @return * returns java.lang.String */ @WebMethod @WebResult(partName = "return") public String getHelloWorldAsString( @WebParam(name = "arg0", partName = "arg0") String arg0); }
File : HelloWorldImplService.java
package com.mkyong.ws; import java.net.MalformedURLException; import java.net.URL; import javax.xml.namespace.QName; import javax.xml.ws.Service; import javax.xml.ws.WebEndpoint; import javax.xml.ws.WebServiceClient; import javax.xml.ws.WebServiceFeature; /** * This class was generated by the JAX-WS RI. * JAX-WS RI 2.1.1 in JDK 6 * Generated source version: 2.1 * */ @WebServiceClient(name = "HelloWorldImplService", targetNamespace = "http://ws.mkyong.com/", wsdlLocation = "http://localhost:9999/ws/hello?wsdl") public class HelloWorldImplService extends Service { private final static URL HELLOWORLDIMPLSERVICE_WSDL_LOCATION; static { URL url = null; try { url = new URL("http://localhost:9999/ws/hello?wsdl"); } catch (MalformedURLException e) { e.printStackTrace(); } HELLOWORLDIMPLSERVICE_WSDL_LOCATION = url; } public HelloWorldImplService(URL wsdlLocation, QName serviceName) { super(wsdlLocation, serviceName); } public HelloWorldImplService() { super(HELLOWORLDIMPLSERVICE_WSDL_LOCATION, new QName("http://ws.mkyong.com/", "HelloWorldImplService")); } /** * * @return * returns HelloWorld */ @WebEndpoint(name = "HelloWorldImplPort") public HelloWorld getHelloWorldImplPort() { return (HelloWorld)super.getPort( new QName("http://ws.mkyong.com/", "HelloWorldImplPort"), HelloWorld.class); } /** * * @param features * A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. * Supported features not in the <code>features</code> parameter will have their default values. * @return * returns HelloWorld */ @WebEndpoint(name = "HelloWorldImplPort") public HelloWorld getHelloWorldImplPort(WebServiceFeature... features) { return (HelloWorld)super.getPort( new QName("http://ws.mkyong.com/", "HelloWorldImplPort"), HelloWorld.class, features); } }
Now, create a Java web service client which depends on the above generated files.
package com.mkyong.client; import com.mkyong.ws.HelloWorld; import com.mkyong.ws.HelloWorldImplService; public class HelloWorldClient{ public static void main(String[] args) { HelloWorldImplService helloService = new HelloWorldImplService(); HelloWorld hello = helloService.getHelloWorldImplPort(); System.out.println(hello.getHelloWorldAsString("mkyong")); } }
Here’s the output
Hello World JAX-WS mkyong
3. Ruby Web Service Client
Often time, web service development is mixed use with other programming language. So, here’s a Ruby web service client example, which is used to access the published JAX-WS service.
# package for SOAP-based services require 'soap/wsdlDriver' wsdl_url = 'http://localhost:9999/ws/hello?wsdl' service = SOAP::WSDLDriverFactory.new(wsdl_url).create_rpc_driver # Invoke service operations. data1 = service.getHelloWorldAsString('mkyong') # Output results. puts "getHelloWorldAsString : #{data1}"
Output
getHelloWorldAsString : Hello World JAX-WS mkyong
Tracing SOAP Traffic
From top to bottom, showing how SOAP envelope flows between client and server. See #1 web service client again :
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"));
To monitor SOAP traffic is very easy, see this guide – “How to trace SOAP message in Eclipse IDE“.
1. Request a WSDL file
First, client send a wsdl request to service endpoint, see HTTP traffic below :
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"?> <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></types> <message name="getHelloWorldAsString"> <part name="arg0" type="xsd:string"></part> </message> <message name="getHelloWorldAsStringResponse"> <part name="return" type="xsd:string"></part> </message> <portType name="HelloWorld"> <operation name="getHelloWorldAsString" parameterOrder="arg0"> <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="rpc"></soap:binding> <operation name="getHelloWorldAsString"> <soap:operation soapAction=""></soap:operation> <input> <soap:body use="literal" namespace="http://ws.mkyong.com/"></soap:body> </input> <output> <soap:body use="literal" namespace="http://ws.mkyong.com/"></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. hello.getHelloWorldAsString()
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>
Done, any comments are appreciated.

I am new to webservice and i tried this tutorial but am facing the below stack trace pls help me ….
Exception in thread “main” Server Runtime Error: class: HelloWorldImpl could not be found
at com.sun.xml.internal.ws.transport.http.server.HttpEndpoint.publish(HttpEndpoint.java:269)
at com.sun.xml.internal.ws.transport.http.server.EndpointImpl.publish(EndpointImpl.java:87)
at com.sun.xml.internal.ws.spi.ProviderImpl.createAndPublishEndpoint(ProviderImpl.java:59)
at javax.xml.ws.Endpoint.publish(Endpoint.java:156)
at com.suji.endpoint.HelloWorldPublisher.main(HelloWorldPublisher.java:12)
Caused by: class: HelloWorldImpl could not be found
at com.sun.xml.internal.ws.modeler.RuntimeModeler.getPortTypeName(RuntimeModeler.java:1289)
at com.sun.xml.internal.ws.server.RuntimeEndpointInfo.doPortTypeNameProcessing(RuntimeEndpointInfo.java:274)
at com.sun.xml.internal.ws.transport.http.server.HttpEndpoint.fillEndpointInfo(HttpEndpoint.java:236)
at com.sun.xml.internal.ws.transport.http.server.HttpEndpoint.publish(HttpEndpoint.java:297)
at com.sun.xml.internal.ws.transport.http.server.HttpEndpoint.publish(HttpEndpoint.java:263)
… 4 more
Thanks for this tuterial
very nice,
Please let me know , Suppose i have developed web service publisher in one java application, then i have developed the client in another java application, i want to access first java application method into the second java application .how can i do this??
Is it possible??
Is there need to import any package or add jar file, how it can make , Please explain , it’s important
Thanks
Vishwajeet
After hitting the service by the client I found the following error:
Exception in thread “main” javax.xml.ws.soap.SOAPFaultException: Found element Request but could not find matching RPC/Literal part
at com.sun.xml.internal.ws.fault.SOAP11Fault.getProtocolException(Unknown Source)
at com.sun.xml.internal.ws.fault.SOAPFaultBuilder.createException(Unknown Source)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(Unknown Source)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(Unknown Source)
at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(Unknown Source)
at com.sun.proxy.$Proxy35.getAccount(Unknown Source)
Any help on this??
Buenas tardes señor Mkyong,
quiero agradecerle, llevo todo el día buscando como se hace eso y en esta entrada encuentro la solución.
Leído desde Bogotá-Colombia!
Muchas gracias!
we implemented one jax-ws webservice using RPC style and published using the following url
http://localhost:9999/ws/hello?wsdl
but when we issue the
wsimport -keep http://localhost:9999/ws/hello?wsdl
command to generate the stub from the jdk bin command prompt wsimport throwing Can not get a WSDL maximum number of redirects(5) reached,
Very nice article to understand web service basics.
If I need to transfer XML, should I use the XML content in form of String? and then parse the string to get results? Any help would be appreciated.
Thanks, easy to understand
How to get hold of the interface of a web service? In my case I don’t have an interface with me, so I used the wsimport tool to do it for me, but the interface created like that is using a objectfactory which is using a wrapper object (name of the class same as that of the method). Hence I have to use all the classes created by the wsimport tool. Should I have to write the interface myself ?
Valuable tutorial
Thanks for great article. It very easy to understand web services basic with it.
But in attached sources archive is one little error. In HelloWorldPublisher.java endpoint port is 9999
when in HelloWorldClient.java port is 8888
After correction to same port app work good.
Best regards
thanks for posting this tutorial..
It was really helpful…
Hello Sir,
Thanks for sharing such helpful and easy to understand tutorials.
I need to consume a web service provided by a client. If i follow the 1st option mentioned in this article. Do i need to create client using
?
I have WSDL.
Please guide. Thanks again !!!
Hi,
You can use :
wsimport “D:\WSDLfile.wsdl” -s “c:\JavaProyect\src”
wsimport “http://www.domain.com/ServiceName?wsdl” -s “c:\JavaProyect\src”
Best Regards
Thanks for the reply.
So, Does it mean that i have to create client for this?
Now you need to create the Web service client from the interfaces generated by the wsimport too
Yes that is what i meant.
Here in this article there are two ways suggested to develop web service client.
In second one it is mentioned that you need to create web service client using wsimport while in first it isn’t.
So, i was under impression that if we follow first approach then we won’t require to create web service client.
Please correct me if i misunderstood. Thanks
Here, i am referring to 1. Java Web Service Client
In which it says “Without tool, you can create a Java web service client like this :”
Great article, thank you very much!
I have a question though: how do we do when we want to call a web service which we don’t have the source code? For example, I want to use the one which gives me the weather’s state. So how do I do in the client?
To generate the client need the URL or endpoint wsdl. You do not need to know the implementation
The first statement is : “JAX-WS is bundled with JDK 1.6″.
So, if I need web services on Websphere, will I need any infrastructure from the application server?
On Tomcat, will I use the web-service provided by JDK?
When will I need some external runtime like AXIS?
Such a great article. Could you also post an article for JAX-WS using maven.
Hi mykyong,
superb tutorial for beginners…and easy to understand..
Thank you so much for great article, it is very understandable for beginners.
But how to catch exceptions and pass it in SOAPFault tag?
For example, i have web service, which makes division operation. How to catch number division by zero and pass it in SOAPFault tag?
Its being some time I was searching intuitive tutorial where I could apply my theoretical knowledge to implement it in reality and finally with your help I am can confidently say I know WebServices.
Thanks a lot!!
Thanks for this example
I am purposefully not using any tool / IDE ( Eclipse ) and am copy pasting your code example in notepad
Then I am compiling the code on dos prompt
The one change is – I removed all the package statements in all classes in above example
When I try and run HelloWorldPublisher I get the exception
In HelloWorldImpl – I changed & commented the code as below:
So while I should not have played with it – I dont seem to understand why it would matter ?
Thanks,
satish
Any Interface or a class should have a name space (which is nothing but the package name), so to implement any web service, we need to make sure we have given the correct namespace so the JAX-WS can publish/expose it’s methods correctly.
Excellent webservices……………..
thanks ..
I’m trying to get my publisher class to run in NetBeans 7.1, but it’s taking forever to run. Any ideas as to why this is happening?
I downloaded your code and checked it with the tcp/ip monitor from eclipse.
Unfortunately, I can only see the wsdl in the first and only response but not the soap traffic. That is because the url will be reread from within the wsdl and that is not with port 8888 but 9999.
Is there a little trick to tell the client not to use the URL from WSDL.
Hi, great article and great webpage overall, you have helped me many times.
I have a question, I need to call a WS method but I want to use a proxy.
How to do it? I tried
but I dont want to do it as I might call the method from concurrent threads…
Thank you
Can you try with this :
BasicHttpBinding binding = new BasicHttpBinding(“APISoap”); /* APISoap is the name of the binding element in the app.config */
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.Basic;
binding.UseDefaultWebProxy = false;
binding.ProxyAddress = new Uri(string.Format(“http://{0}:{1}”, proxyIpAddress, proxyPort));
EndpointAddress endpoint = new EndpointAddress(“http://www.examplewebservice/api.asmx”);
WebServiceClient client = new WebServiceClient(binding, endpoint);
client.ClientCredentials.UserName.UserName = proxyUserName;
client.ClientCredentials.UserName.Password = proxyPassword;
thank you for the reply but I have already implemented a proxy by extending class ProxySelector.
Tried to implement this into my project but I’m unable to create JAXBContext due to handle interfaces?
Any ideas or suggestions?
Heres the message:
PingRequest is an interface, and JAXB can’t handle interfaces.
Just wanted to leave a note to say a great article/tutorial. Was trapsing through the Oracle site and my mind boggled thinking how complex this whole thing was, and then luckily I found this!
Thank you so much….. Very much useful for the beginners….
-How I can change Content-type to application / soap + xml, using a jaxws web service client,
-Anyone know how to configure the endpoint using HttpURLConnection, it should be noted that I can only assign the url to the wsdl definition but additionally need to assign different endpoint from this library. in conclusion would need to configure a url and a different endpoint to consume the service url
Thanks for the comprehensive tutorial. Do you know how to override the default behaviour of the ‘GET’ http Method when using ‘Endpoint’ ?
Your Articles are very easy to understand, thank you for the posting.
I have some problem in consuming the webservice with ssl.
I have generated the client code using Axis2
I have a certificate MyCertificate.cer generated as per the instructions from the Webservice Provider.
I am struct at coding the client could you please help or post an article how to consume ssl webservice , using certificate in cleint.
Nice article, thanks a lot.
I’m having a problem with the TCP/IP monitor view in Eclipse (Juno – on Mac OS X).
When I run your example (or my own code) I’m only seeing the first request/response i.e. I see all the expected request/response info you listed in the “1. Request a WSDL file” section
But nothing gets logged in TCP/IP monitor for this part “2. hello.getHelloWorldAsString()”. Even if I make multiple calls to it..
Has anyone else had this problem?