Java JAX-WS Tutorial: Develop Web Services and Clients (Consumers) Using JAX-WS

0 Flares Twitter 0 Facebook 0 Google+ 0 LinkedIn 0 Email -- Filament.io 0 Flares ×

Java JAX-WS Tutorial to Develop your First Web Service Using JAX-WS API, Eclipse, wsimport and wsgen Tools without using JEE Containers.

This article gives an introduction and quick start guide on JAX-WS, the Java API for XML Web Services. This tutorial explains about how to create the Service Endpoint Interface, implementation classes, usage of annotations defined in JAX-WS API, wsimport tool, wsgen tool, WSDL, how to manually publish the endpoint and finally how to create a web service client to consume the web service.
You can use any IDE such as Eclipse to run and execute the examples provided in this tutorial. You need to have Java version 6 or above installed in your machine to use this tutorial.

JAX-WS Overview

JAX-WS or Java API for XML Web Services is a java technology specification for building message oriented as well as RPC oriented web services. JAX-WS helps you to develop web services and web service clients with minimum coding as the JAX-WS API hides the complexity of SOAP messages from the application developer. The SOAP specification defines the SOAP Message envelope structure, encoding rules, and conventions for representing web service invocations and responses which are transmitted as SOAP messages (XML files) over HTTP.
JAX-WS Web Services and Clients
JAX-WS 2.0 supports the Web Services Interoperability (WS-I) Basic Profile Version 1.1 , so, the JAX-WS runtime supports doc/literal and rpc/literal encodings for services, static ports, dynamic proxies, and DII. JAX-WS is also one of the foundations of web service interoperability Technologies (WSIT). The reference implementation (RI) of JAX-WS is part of the Metro distribution, which also includes Project Tango which handles the WSIT.

From Java Version 6 onwards JAX-WS can be used in Java SE.

First let us discuss the approaches you can adopt when you start developing a web service project. You can follow either the bottom-up approach or top-down approach.

  •   In top-down approach, you can start web service development with a WSDL service contract and generate Java objects to implement the service.
  •   In bottom-up approach you start web service development with a Java object and service enable it using annotations.

Top-down approach: Start with WSDL

When you start with WSDL you first define your services in the WSDL document. You can generate java classes from WSDL, if the document contains logical interfaces. When you create java classes using a WSDL the following conversions happens.

  •   The logical interface, defined by the wsdl:portType element, is mapped to a SEI (service endpoint interface ) • The complex types are mapped to Java Clasess following JAXB sepecification.
  •   The endpoint defined by the wsdl:service element is generated into a Java class. This java class is used by consumers to access endpoints implementing the service.

You can use wsimport tool to generate the java classes from WSDL document.

Bottom-up approach: Start with Java Classes

In bottom-up approach we create the service end point interface (SEI) first. You define the methods in SEI that you expose as services. SEI typically is a standard Java interface. This is going to be the “wsdl:portType “ element in your WSDL document. The methods defined in SEI will become the “wsdl:operation” elements in the “wsdl:portType element” in WSDL. You need to annotate the SEI interface with required JAX-WS annotations.

Let us have a closer look at the different annotations provided by the JAX-WS API and how and when we use them.

The @WebService annotations

The “@WebService” should be placed on an interface and a class that is intended to be used as a service. It has the following attributes.

  •   name: Specifies the name of the service interface and iss mapped to the name attribute of the wsdl:portType element in a WSDL contract document.
  •   targetNamespace: Specifies the target namespace under which the service is defined.(Default value is package name).
  •   serviceName: Specifies the name of the published service. This property is mapped to the name attribute of the wsdl:service element in WSDL document. (Default value is name of SEI implementation class. This attribute is used in implementation class).
  •   wsdlLocation: Specifies the URI at which the service’s WSDL contract is stored. (Default value is the URI at which the service is deployed).
  •   endpointInterface: Specifies the full name of the SEI that the implementation class implements.(This attribute is used in implementation class).
  •   portName: The name of the endpoint at which the service is published and is mapped to the name attribute of the wsdl:port element in WSDL contract document.(Default value is the append Port to the name of the service’s implementation class. This is used in implementation class).

The service implementation class is annotated with @webservice and can include additional attributes such as endpointInterface, portName , serviceName etc.

The @SOAPBinding annotation

By default the JAX-WS runtime engine uses the wrapped doc/literal SOAP binding if you don’t specify any. To specify the required SOAP binding you can use the @SOAPBinding annotation. You can add @SOAPBinding annotation to the SEI and its methods. The latter takes precedence if you use both.
You can read more about SOAP Binding styles. The following are the attributes of @SOAPBinding annotation.

  • style: The values can be either DOCUMENT or RPC
  •  use: The values can be LITERAL or ENCODED
  •  parameterStyle: The value can be BARE or WRAPPED.

The @WebMethod annotation

You need to add the @WebMethod annotation provides the information that is normally represented in the wsdl:operation element in WSDL. This indicates the operation to which the method is associated.

  •  operationName: Indicates the value of the associated wsdl:operation element’s name. (Default value is the name of the method).
  •  action: This attribute specifies the value of the soapAction attribute of the soap:operation element for the method in WSDL. (Default value is an empty string).
  •  exclude: Specifies whether the method should be excluded from the service interface.(Default is false. But it is recommended that the SEI ideally should contain only the required methods which are required to be published).

The @RequestWrapper and @ResponseWrapper annotations

These annotations are placed on the methods in service endpoint interface. The @RequestWrapper specifies the Java class that implements the wrapper bean for the method parameters that are included in the request message sent in a remote invocation and the @ResponseWrapper specifies the Java class that implements the wrapper bean for the method parameters that are included in the response message sent in a remote invocation.
These annotations have localName, targetNamespace and className attributes and only className is mandatory.

The @WebFault annotation

The @WebFault annotation is used to map the Java exception to a wsdl:fault element. @WebFault is placed on exceptions that are thrown by your SEI. This has the the attributes name, targetNamespace and faultName attributes

The @Oneway annotation

The @Oneway annotation is placed on the methods in the SEI that will not require a response from the service. The runtime does not wait for a response and will not reserve any resource to process a response.

The @WebParam annotation

The @WebParam annotation allows you to specify the direction of the parameter, if the parameter will be placed in the SOAP header, and other properties of the generated wsdl:part. This annotation is placed on the parameters on the methods defined in the SEI. This annotation has the following attributes.

  •  name: Specifies the name of the parameter as it appears in the WSDL. For RPC bindings, this is name of the wsdl:part representing the parameter. For document bindings, this is the local name of the XML element representing the parameter.
  •  targetNamespace: Indicates the namespace for the parameter(Defaults is to use the service’s namespace).
  •  mode: Indicates the direction of the web parameter. Values can be Mode.IN (default) ,Mode.OUT or Mode.INOUT
  • head: This indicates if the parameter is passed as part of the SOAP header. Values can be Mode.IN (default) ,Mode.OUT or Mode.INOUT
  • partName: Indicates the value of the name attribute of the wsdl:part element for the parameter when the binding is document.

The @WebResult annotation

The @WebResult annotation allows you to specify the properties of the generated wsdl:part that is generated for the method’s return value. This annotation is placed on the methods defined in the SEI. This annotations has name, targetNamespace, header and partName attributes in which header specifies if the return value is passed as part of the SOAP header.

JAX-WS Web Service and Client (Consumer) Example and Source Code

Now, since we got some insight into the annotations used in JAX-WS web services, let us define our first service end point interface (SEI).

The SEI (Service Endpoint Interface)

/**
 * @author Binu George
 * Globinch.com
 * Visit  http://www.globinch.com. All rights reserved.
 */
package com.my.ws;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.WebParam.Mode;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.jws.soap.SOAPBinding.Use;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;

@WebService(name = "MyJaxWSHello", 
		targetNamespace = "http://globinch.com", 
		wsdlLocation = "http://globinch.com/ws/MyJaxWS?wsdl")
@SOAPBinding(style=Style.RPC, use=Use.LITERAL)		
public interface MyJaxWSSEI {

	  @WebMethod(operationName="getJXWsRes")
	  @RequestWrapper(targetNamespace="http://globinch.com/ws/types",
	     className="java.lang.String")
	  @ResponseWrapper(targetNamespace="http://globinch.com/ws/types",
	     className="com.my.ws.JXRes")
	  @WebResult(targetNamespace="http://globinch.com/ws/types",
	     name="JXWsRes")
	  public JXRes getJXWsRes(
	     @WebParam(targetNamespace="http://globinch.com/ws/types",
	               name="name",
	               mode=Mode.IN)
	               String name
	  );

}

The SEI implementation class

/**
 * @author Binu George
 * Globinch.com
 * Visit  http://www.globinch.com. All rights reserved.
 */
package com.my.ws;

import javax.jws.WebService;

@WebService(endpointInterface="com.my.ws.MyJaxWSSEI",
		   targetNamespace="http://globinch.com",
		   portName="MyJaxWSSEIPort",
		   serviceName="MyJaxWSHelloService")
public class MyJaxWSSEIImpl implements MyJaxWSSEI {

	/**
	 * Default Constructor
	 */
	public MyJaxWSSEIImpl() {

	}

	/* (non-Javadoc)
	 * @see com.my.ws.MyJaxWSSEI#getJXWsRes(java.lang.String)
	 */
	@Override
	public JXRes getJXWsRes(String name) {
		JXRes jxRes = new JXRes();
		jxRes.setMessage("Hello");
		jxRes.setName(name);
		return jxRes;
	}

}

The entity -Wrapper Bean

/**
 * @author Binu George
 * Globinch.com
 * Visit  http://www.globinch.com. All rights reserved.
 */
package com.my.ws;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class JXRes {
	protected String message;
	protected String name;
	/**
	 * 
	 */
	public JXRes() {
		super();
		// TODO Auto-generated constructor stub
	}
	/**
	 * @return the id
	 */
	public String getMessage() {
		return message;
	}
	/**
	 * @param id the id to set
	 */
	public void setMessage(String message) {
		this.message = message;
	}
	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}
	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

}

Publishing the Web Service End Point

Now publish the endpoint so that we can do a quick test of our web service.
In an actual project you may not include this part of this tutorial. The application server is responsible for publishing the web services based on your web service SEI and other classes.

/**
 * @author Binu George
 * Globinch.com
 * Visit  http://www.globinch.com. All rights reserved.
 */

package com.my.ws;

import javax.xml.ws.Endpoint;

public class JXResTest {
	 public static void main(String[] args ){
	        Endpoint.publish("http://yourmachineip:8088/MyJaxWSService", new MyJaxWSSEIImpl());
	    }
}

Now you need to run the EndPoint publisher class.

Go to command prompt based on your Java project classpath and run the following command

java com.my.ws.JXResTest

jax-ws Endpoint publisher

Review the published WSDL

Now the web service is published. Open the browser and see the WSDL by going to “http://yourmachineip:8088/MyJaxWSService?wsdl

You will see the WSDL as follows.



	
	

	
		
			
		
	
	
		
	
	
		
	
	
		
			
			
		
	
	
		
		
			
			
				
			
			
				
			
		
	
	
		
			
		
	

Test the Web Service :Write Web Service Client

Now you need to test our service. For this we need to create a web service client. Let us use the wsimport  for generating the client classes. Go to the project base directory and execute the following command.

wsimport -keep -d E:\\MyWS\src\ http://192.168.1.201:8088/MyJaxWSService?wsdl

wsimport

This will generate the following java files (and classes).

  •  JxRes.java
  • MyJaxWSHello.java
  • MyJaxWSHelloService.java
  • ObjectFactory.java
  • package-info.java

Now we can write our client class using these generated classes.

/**
 * @author Binu George
 * Globinch.com
 * Visit  http://www.globinch.com. All rights reserved.
 */
package com.my.ws.client;

import javax.xml.ws.WebServiceRef;

import com.globinch.JxRes;
import com.globinch.MyJaxWSHello;
import com.globinch.MyJaxWSHelloService;

public class JaxWSClient {

	 @WebServiceRef(wsdlLocation="http://192.168.1.201:8088/MyJaxWSService?wsdl")
	  static MyJaxWSHelloService service;
	/**
	 * @param args
	 */
	 public static void main(String[] args) {
		    try {
		   	JaxWSClient client = new JaxWSClient();
		      client.doTest(args);
		    } catch(Exception e) {
		      e.printStackTrace();
		    }
		  }

		  public void doTest(String[] args) {
		    try {
		      service = new MyJaxWSHelloService();
		      MyJaxWSHello port = service.getMyJaxWSSEIPort();
		      String name;
		      if (args.length > 0) {
		        name = args[0];
		      } else {
		        name = "Globinch";
		      }
		      JxRes response = port.getJXWsRes(name);
		      System.out.println("************************");
		      System.out.println(response.getMessage()+" "+response.getName());
		      System.out.println("************************");
		    } catch(Exception e) {
		      e.printStackTrace();
		    }
		  }
}

Run the JAX-WS Client and Test the Published Web Service.

Now our endpoint is already running , since the Endpont publisher class is still running.

Go to the your projects base directory , open a command prompt and run the following commands.

java com.my.ws.client.JaxWSClient Globinch

You will see the response as below

run jax-ws client

Other Points: Using wsgen tool to generate WSDL and required XML Schema documents

You can also use the wsgen  to create the WSDL and XML Schema file from the service implementation class. Go to the project base directory and execute the following command.
Open a command prompt and type as follows. Remember to change the locations based on your project paths.

wsgen -keep -r E:\MyWS\build\gen -s E:\MyWS\build\gen -verbose -cp . com.my.ws.MyJaxWSSEIImpl  -wsdl

wsgen tool
This will generate two files

  • MyJaxWSHelloService_schema1.xsd
  • MyJaxWSHelloService.wsdl

MyJaxWSHelloService.wsdl





  
    
      
    
  
  
    
  
  
    
  
  
    
      
      
    
  
  
    
    
      
      
        
      
      
        
      
    
  
  
    
      
    
  

MyJaxWSHelloService_schema1.xsd




  
  
    
      
      
    
  


Incoming search terms:

0 Flares Twitter 0 Facebook 0 Google+ 0 LinkedIn 0 Email -- Filament.io 0 Flares ×

Related Posts

This Post Has 27 Comments

  1. Hello Satya, Surender,Reena and Abhas,

    Thanks for stopping by. Please let me know if you need any help on the examples published on Globinch Java Forum.

    Thanks
    Binu George

  2. Hi Binu, I want to write a web service client to access a secured third party web service. I have server url pointing to WSDL. I have already generated client code by using eclipse tool. Now I am stuck as I am very new to web service development and need your help.
    Can you please guide me how I can write a client code with authenticating it and providing Proxy settings of my company.

  3. I just tried @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE) and changed @WebParam by providing targetNamespace=”mine”, name=”xyz”,partName=”xyz” and did the same for @webresult(targetNamespace=”mine”,name=”abc”, partName=”abc”. It works fine.

  4. excellent and at a single stretch u taught how to create a web service and how a client can use that..Also the highlighted one is the usage of tools WSImport and Wsgen ..hats off to the work

  5. Hi Binu, I want to write a web service client to access a secured third party web service. I have server url pointing to WSDL. I have already generated client code by using wsimport tool. Not sure how to pass userid and password for authentication. Using JAX-WS and RAD 7.5. Appreciate your help.

    Regards.

  6. I’ve been looking for sometime for information about SOAP Web Services using complex types. This is the best tutorial I found in many days. Thanks for sharing!

  7. Hi,

    I am loving your article. I had to stop reading to comment and tell you this. Many of my concepts got cleared just by reading the first half of the article. Thank you for giving such clear explanation.

    Thanks,
    Pooja

  8. Hello Binu,
    Please let me know the security approaches,If it is possible with example,Please introduce.
    One more thing, how can i restrict client(which consume WS) for a limited time period like as 1 Year,2 Year…n

    Thanks.

  9. Hai Binu George,
    is it standard way to assign Map in wsdl. I dont know to set the value for that map. when i am acting like a client.

  10. I am struck at setting value of the map . please provide one example using parameter as Map for method
    ex:
    public boolean getDynamicParameters(@WebParam(name = “mapEntity”) Map dynamicParams);
    My goal is achieve Dynamic Service provider. it has to accept all the parameters And at same time i am not able to set values for map when i am act as a client. Please suggest how can i achieve this.

  11. Thanks Binu,It was very useful. I am having (xerox)printing wsdl files, which i think i can pass parameters from my computer(eclipse) to xerox machine(printer). how to publish the wsdl file which is given by xerox people and how to access it in client program.

  12. Hi,
    I am Tanmay Sonawane, I want to communicate with the soap web services, I am created the JAX-WS by using the wsimport but i will try to use those classes like to perform Logon then the following Exception is thrown and, I am not able to make any changes in soap wsdl. I want to use these web services as it is, below mention classes created using wsimport
    1) Webservice -class————ie.service name in wsdl
    2) WebserviceSoapPort-Interface———-i.e port name in wsdl

    Webservice service=new Webservice();
    WebserviceSoapPort soapPort=service.getWebserviceSoapPort();
    LogonResult result=soapPort.logOn();
    System.out.println(result.getSessionId)

    Below is the EXception happen

    Exception in thread “main” com.sun.xml.internal.ws.protocol.soap.MessageCreationException: Couldn’t create SOAP message due to exception: XML reader error: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
    Message: Content is not allowed in prolog.
    at com.sun.xml.internal.ws.encoding.SOAPBindingCodec.decode(Unknown Source)
    at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.createResponsePacket(Unknown Source)
    at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.process(Unknown Source)
    at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.processRequest(Unknown Source)
    at com.sun.xml.internal.ws.transport.DeferredTransportPipe.processRequest(Unknown Source)
    at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Unknown Source)
    at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Unknown Source)
    at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Unknown Source)
    at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Unknown Source)
    at com.sun.xml.internal.ws.client.Stub.process(Unknown Source)
    at com.sun.xml.internal.ws.client.sei.SEIStub.doProcess(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.$Proxy39.logon(Unknown Source)
    at com.tanmay.client.LogInClient.main(LogInClient.java:24)
    Caused by: com.sun.xml.internal.ws.streaming.XMLStreamReaderException: XML reader error: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
    Message: Content is not allowed in prolog.
    at com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil.wrapException(Unknown Source)
    at com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil.next(Unknown Source)
    at com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil.nextContent(Unknown Source)
    at com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil.nextElementContent(Unknown Source)
    at com.sun.xml.internal.ws.encoding.StreamSOAPCodec.decode(Unknown Source)
    at com.oracle.webservices.internal.impl.encoding.StreamDecoderImpl.decode(Unknown Source)
    at com.sun.xml.internal.ws.encoding.StreamSOAPCodec.decode(Unknown Source)
    at com.sun.xml.internal.ws.encoding.StreamSOAPCodec.decode(Unknown Source)
    … 16 more
    Caused by: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
    Message: Content is not allowed in prolog.
    at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(Unknown Source)
    at com.sun.xml.internal.ws.util.xml.XMLStreamReaderFilter.next(Unknown Source)
    … 23 more

    Please help me

Leave a Reply

Your email address will not be published. Required fields are marked *

Paged comment generated by AJAX Comment Page
© 2024 Globinch Java Forum - Theme by WPEnjoy · Powered by WordPress