Web services - in my simplistic view, these are the software components exposed over web (HTTP) as a service so various other programs or software modules can be able to interact. For easier understanding purpose, it is similar to how a web application deployed on an application server exposes its functions through a UI that a client program like internet browsers can access and display it. Web service even though communicate over HTTP, the exchange of information happens in an XML document with certain rules - called as SOAP (Simple Object Access Protocol)
Java provides an API to develop these components. This is called JAX-WS (Java API for XML Web Services).
And these can be implemented in 2 ways - RPC (remote procedure call) and in a message oriented i.e. in a document style
As this API makes it so simple, we just need below components to develop a simple webservice using JAX-WS
Lets see an RPC style implementation
1. Need a remote i.e. endpoint interface class
2. A remote implementation class
3. A remote publisher class
4. And a client
Below is the self explainable simple code logic
----------------
package com.myWSPackage;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
@WebService
@SOAPBinding(style = Style.RPC)
public interface IamJustAnInterface{
@WebMethod String implementMe(String name);
}
----------------
package com.myWSPackage;
import javax.jws.WebService;
@WebService(endpointInterface = "com.myWSPackage.IamJustAnInterface")
public class IamAnImplementer implements IamJustAnInterface{
@Override
public String implementMe(String name) {
try{Thread.sleep(10000);}catch(Exception e){}
return "Hi There - at your service : " + name;
}
}
-------------------
package com.myWSPackage;
import javax.xml.ws.Endpoint;
public class IamAPublisher{
public static void main(String[] args) {
Endpoint.publish("http://localhost:7777/ws/hi", new IamAnImplementer());
}
}
---------------
package com.myWSPackage;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
public class WSClient{
public static void main(String[] args) throws Exception {
URL url = new URL("http://localhost:7777/ws/hi?wsdl");
QName qname = new QName("http://myWSPackage.com/", "IamAnImplementerService");
Service service = Service.create(url, qname);
IamJustAnInterface ifi = service.getPort(IamJustAnInterface.class);
System.out.println(ifi.implementMe("Buddy"));
}
}
---------------------------------------------------
what happens on the client:
I have intentionally put a sleep in the service interface implementation class to capture the stacks
SocketNativeIO.readBytesPinned(FileDescriptor, byte[], int, int, int)
SocketNativeIO.socketRead(FileDescriptor, byte[], int, int, int) line: 32
SocketInputStream.socketRead0(FileDescriptor, byte[], int, int, int)
SocketInputStream.read(byte[], int, int) line: 129
BufferedInputStream.fill() line: 218
BufferedInputStream.read1(byte[], int, int) line: 258
BufferedInputStream.read(byte[], int, int) line: 317
HttpClient.parseHTTPHeader(MessageHeader, ProgressSource, HttpURLConnection) line: 690
HttpClient.parseHTTP(MessageHeader, ProgressSource, HttpURLConnection) line: 633
HttpURLConnection.getInputStream() line: 1195
HttpURLConnection.getResponseCode() line: 379
HttpClientTransport.readResponseCodeAndMessage() line: 198
HttpTransportPipe.process(Packet) line: 151
HttpTransportPipe.processRequest(Packet) line: 83
DeferredTransportPipe.processRequest(Packet) line: 78
Fiber.__doRun(Tube) line: 587
Fiber._doRun(Tube) line: 546
Fiber.doRun(Tube) line: 531
Fiber.runSync(Tube, Packet) line: 428
Stub.process(Packet, RequestContext, ResponseContextReceiver) line: 211
SEIStub.doProcess(Packet, RequestContext, ResponseContextReceiver) line: 124
SyncMethodHandler.invoke(Object, Object[], RequestContext, ResponseContextReceiver) line: 98
SyncMethodHandler.invoke(Object, Object[]) line: 78
SEIStub.invoke(Object, Method, Object[]) line: 107 ----> proxy and stub creation has been taken care by JDK
$Proxy19.implementMe(String) ---------> is the remote call to the webservice's method
WSClient.main(String[]) line: 15 ---------> is our client main method
what happens on the server side
Thread.sleep(long) ------> just sleeps for 10 sec before it sends out the response
IamAnImplementer.implementMe(String) line: 11 ---> call to the interface method which was exposed as a service
NativeMethodAccessorImpl.invoke0(Method, Object, Object[])
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object[]) line: 597
InstanceResolver$1.invoke(Packet, Method, Object[]) line: 235
InvokerTube$2.invoke(Packet, Method, Object[]) line: 135
EndpointMethodHandler.invoke(Packet) line: 246
SEIInvokerTube.processRequest(Packet) line: 82
Fiber.__doRun(Tube) line: 587
Fiber._doRun(Tube) line: 546
Fiber.doRun(Tube) line: 531
Fiber.runSync(Tube, Packet) line: 428
WSEndpointImpl$2.process(Packet, WebServiceContextDelegate, TransportBackChannel) line: 232
HttpAdapter$HttpToolkit.handle(WSHTTPConnection) line: 460
HttpAdapter.handle(WSHTTPConnection) line: 233
WSHttpHandler.handleExchange(HttpExchange) line: 95
WSHttpHandler.handle(HttpExchange) line: 80
Filter$Chain.doFilter(HttpExchange) line: 65
AuthFilter.doFilter(HttpExchange, Filter$Chain) line: 65
Filter$Chain.doFilter(HttpExchange) line: 68
ServerImpl$Exchange$LinkHandler.handle(HttpExchange) line: 557
Filter$Chain.doFilter(HttpExchange) line: 65
ServerImpl$Exchange.run() line: 529
ThreadPoolExecutor$Worker.runTask(Runnable) line: 886
ThreadPoolExecutor$Worker.run() line: 908
Thread.run() line: 662 ----> the publisher start a thread starts
The document style implementation is all the same way as above except the style declared in the remote
interface class will change to DOCUMENT.
The WSDL will be different for each of these implementations although there seems to be no change in the execution path i.e. stack traces shown above.
In Java EE7, there is support to implement RESTful webservices through the API called JAX-RS.
These are best suited when there is no need for state maintenance, can rely on underlying server caching mechanism and the content will not change dynamically and for light weight message exchanges like handsets, portable communication devices etc,. The RESTful services do not require XML messages or WSDL based API implementations.. They depend/implement the REST verbs like PUT/GET/POST/DELETE.. the implementation is very simple - a root reosource class annotated with the @PATH tells where the implemented java class is located and its methods annotated with the verbs like @GET, @Producer etc., tells which type of request handling will be done, what kind of text will be produced and the output etc., the servlet mapping defined the application's web.xml will tell the resource path and the mapped classes ro invoke.