Sitemap

Wednesday, September 16, 2015

SOAP-based web service in Java

TimeServer.java
package com.sonal;

import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;

/**
 * SEI for a web service that returns the current time as either a string or as
 * the elapsed milliseconds from the Unix epoch, midnight January 1, 1970 GMT.
 * 
 * The annotation @WebService signals that this is the SEI (Service Endpoint
 * Interface). @WebMethod signals that each method is a service operation.
 *
 * The @SOAPBinding annotation impacts the under-the-hood construction of the
 * service contract, the WSDL (Web Services Definition Language) document.
 */
@WebService
@SOAPBinding(style = Style.DOCUMENT)
public interface TimeServer {
 @WebMethod
 String getTimeAsString();

 @WebMethod
 long getTimeAsElapsed();
}


TimeServerImpl.java
package com.sonal;

import java.util.Date;
import javax.jws.WebService;

/**
 * The @WebService property endpointInterface links this SIB (Service
 * Implementation Bean) to the SEI (com.sonal.TimeServer). Note that the method
 * implementations are not annotated as @WebMethods.
 */
@WebService(endpointInterface = "com.sonal.TimeServer")
public class TimeServerImpl implements TimeServer {
 public String getTimeAsString() {
  return new Date().toString();
 }

 public long getTimeAsElapsed() {
  return new Date().getTime();
 }
}


TimeServerPublisher.java
package com.sonal;

import javax.xml.ws.Endpoint;

/**
 * This application publishes the web service whose SIB is
 * com.sonal.TimeServerImpl. For now, the service is published at network address
 * 127.0.0.1., which is localhost, and at port number 9876, as this port is
 * likely available on any desktop machine. The publication path is /ts, an
 * arbitrary name.
 *
 * The Endpoint class has an overloaded publish method. In this two-argument
 * version, the first argument is the publication URL as a string and the second
 * argument is an instance of the service SIB, in this case
 * com.sonal.TimeServerImpl.
 *
 * The application runs indefinitely, awaiting service requests. It needs to be
 * terminated at the command prompt with control-C or the equivalent.
 *
 * Once the application is started, open a browser to the URL
 *
 ** http://127.0.0.1:9876/ts?wsdl
 *
 * to view the service contract, the WSDL document. This is an easy test to
 * determine whether the service has deployed successfully. If the test
 * succeeds, a client then can be executed against the service.
 */

public class TimeServerPublisher {
 public static void main(String[] args) {
  // 1st argument is the publication URL
  // 2nd argument is an SIB instance
  Endpoint.publish("http://127.0.0.1:9876/ts", new TimeServerImpl());
 }
}



WSDL document for the TimeServer service
<?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.2.4-b01. -->
<!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.2.4-b01. -->
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://sonal.com/" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://sonal.com/" name="TimeServerImplService">
   <types>
      <xsd:schema>
         <xsd:import namespace="http://sonal.com/" schemaLocation="http://127.0.0.1:9876/ts?xsd=1" />
      </xsd:schema>
   </types>
   <message name="getTimeAsString">
      <part name="parameters" element="tns:getTimeAsString" />
   </message>
   <message name="getTimeAsStringResponse">
      <part name="parameters" element="tns:getTimeAsStringResponse" />
   </message>
   <message name="getTimeAsElapsed">
      <part name="parameters" element="tns:getTimeAsElapsed" />
   </message>
   <message name="getTimeAsElapsedResponse">
      <part name="parameters" element="tns:getTimeAsElapsedResponse" />
   </message>
   <portType name="TimeServer">
      <operation name="getTimeAsString">
         <input wsam:Action="http://sonal.com/TimeServer/getTimeAsStringRequest" message="tns:getTimeAsString" />
         <output wsam:Action="http://sonal.com/TimeServer/getTimeAsStringResponse" message="tns:getTimeAsStringResponse" />
      </operation>
      <operation name="getTimeAsElapsed">
         <input wsam:Action="http://sonal.com/TimeServer/getTimeAsElapsedRequest" message="tns:getTimeAsElapsed" />
         <output wsam:Action="http://sonal.com/TimeServer/getTimeAsElapsedResponse" message="tns:getTimeAsElapsedResponse" />
      </operation>
   </portType>
   <binding name="TimeServerImplPortBinding" type="tns:TimeServer">
      <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
      <operation name="getTimeAsString">
         <soap:operation soapAction="" />
         <input>
            <soap:body use="literal" />
         </input>
         <output>
            <soap:body use="literal" />
         </output>
      </operation>
      <operation name="getTimeAsElapsed">
         <soap:operation soapAction="" />
         <input>
            <soap:body use="literal" />
         </input>
         <output>
            <soap:body use="literal" />
         </output>
      </operation>
   </binding>
   <service name="TimeServerImplService">
      <port name="TimeServerImplPort" binding="tns:TimeServerImplPortBinding">
         <soap:address location="http://127.0.0.1:9876/ts" />
      </port>
   </service>
</definitions>

The portType section, near the top, groups the operations that the web service delivers, in this case the operations getTimeAsString and getTimeAsElapsed, which are the two Java methods declared in the SEI and implemented in the SIB. The WSDL portType is like a Java interface in that the portType presents the service operations abstractly but provides no implementation detail.
The other WSDL section of interest is the last, the service section, and in particular the service location, in this case the URL http://localhost:9876/ts. The URL is called the service endpoint and it informs clients about where the service can be accessed.

TimeClient.java
package com.sonal;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.net.URL;

class TimeClient {
 public static void main(String args[]) throws Exception {
  URL url = new URL("http://localhost:9876/ts?wsdl");
  // Qualified name of the service:
  // 1st arg is the service URI
  // 2nd is the service name published in the WSDL
  QName qname = new QName("http://sonal.com/", "TimeServerImplService");
  // Create, in effect, a factory for the service.
  Service service = Service.create(url, qname);
  // Extract the endpoint interface, the service "port".
  TimeServer port = service.getPort(TimeServer.class);
  System.out.println(port.getTimeAsString());
  System.out.println(port.getTimeAsElapsed());
 }
}


No comments:

Post a Comment