SOAP Webservices (JAX-WS)

Introductie

Webservices zijn applicaties waarvan het interface via internet benaderbaar zijn door berichtuitwisseling over het http protocol. Webservices bieden daarmee een loosely coupled implementatie van een Client/Server architectuur. Webservice Server applicaties bieden een API die door Webservice Client applicaties worden benaderd. Webservices zijn technologie onafhankelijk, kunnen draaien op elk operating system platform en kunnen worden geimplementeerd in verschillende ontwikkeltechnologieen zoals Java /JEE en C#/.Net.
Er zijn op hoog niveau 2 soorten Webservice: SOAP en REST. De meest voorkomende en ook traditionele Webservice is een SOAP (Simple Object Access Protocol) Webservice en is voor het Java platform gebaseerd op de JEE JAX-WS standaard. De SOAP webservice wordt ook wel aangeduid als “Big”Webservice omdat deze gebruik maakt van XML als berichten structuur. Dit in tegenstelling tot de REST (Representational State Transfer) Webservice, gebaseerd op de JEE JAX-RS standaard, die verschillende berichtformaten kan toepassen, waaronder naast XML, vooral het lichtere JSON formaat. Het JSON formaat is met name van belang voor interactie met JavaScript clients in Ajax gebaseerde Rich Client en Mobile applicaties. JSON is namelijk binnen JavaScript de standaard voor data objecten.

SOAP is een Webservice standaard met een XML taal voor een Webservice bericht architectuur en formaat beschrijving. SOAP beschrijft de operaties van een Webservice interface met de XML gebaseerde taal WSDL (Web Service Description Language). Met WSDL worden de operaties en berichtstructuren syntactisch gespecificeerd. Het SOAP berichtformaat en de WSDL interface specificatie zijn de belangrijkste bouwstenen voor het ontwikkelen van Webservices in de meeste ontwikkelplatforms. Aanvankelijk werd vanuit een WSDL definitie de interface code ontwikkeld of gegenereerd. Met de JEE JAX-WS standaard zijn echter zeer eenvoudige Webservices te maken door Java structuren zoals gewone Java Pojo classes of EJB Enterprise Beans te voorzien van de @WebService annotatie en de methods van de @WebMethod annotatie. In een JEE container worden de classes en methods automatisch gepubliceerd als SOAP Web services en operaties. De @WebService annotatie definieert een Java class als een Webservice endpoint. Een service endpoint interface (SEI) definieert de methods die een client kan aanroepen.
Bij het deployen van een class met de @WebService annotatie in een JEE container wordt de WSDL specificatie ook automatisch opgesteld vanuit de method definities en de daarvoor gebruikte datatypes.

WSDL

Een WSDL definitie is een xml document en bestaat uit de volgende onderdelen:

  • definitions: het xml root element met als attributen naam waarmee de webservice wordt gepubliceerd en de gebruikte namespace waarbinnen deze naam uniek is.
  • types: de gebruikte datatype definities binnen de messages
  • message: definitie van de gebruikte berichten inhoud en structuur
  • portType: de set operaties van de webservice, dat wat door clients kan worden aangeroepen en dus feitelijke de essentie van het geheel
  • binding: de gebruikte protocollen en dataformats

Zie hieronder een voorbeeld op root niveau:

Hieronder is in de portType te zien dat de operatie “update” een input message “update” en een output message “updateResponse” gebruikt:

In de lijst messages is de message “update” te zien. Hieronder wordt de specificatie uitgelicht:

Hierin is te zien dat de message “update” een part van type “update” gebruikt. In de lijst types is deze als element te zien die weer als complexType “update” is gedefinieerd:

Het complexType is opgebouwd uit de uiteindelijke atomaire elementen. Elk atomair element heeft primitieve datatypes zoals int, long,en string.

SOAP Webservice implementatie

Onderstaand voorbeeld geeft aan hoe met de annotatie @WebService een JavaBean als een webservice wordt gedefinieerd. De JavaBean is in dit geval een Stateless EJB Session Bean, gedefinieerd met de @Stateless annotatie.

@Stateless
@WebService(
        portName = "DepartmentPort",
        serviceName = "DepartmentServiceWS",
        targetNamespace = "http://biz.org/wsdl",
        endpointInterface = "org.biz.employeesSOAP.ws.DepartmentService")
public class DepartmentServiceWS implements DepartmentService {
}

Voor de @WebService worden de volgende attributen gespecificeerd:

  • portName : de naam van de Webservice port die in de WSDL wordt gebruikt.
  • serviceName : de naam waarmee de Webservice door de container wordt gepubliceerd. Hier is gekozen voor de naam van de implementerende class
  • targetNamespace: de namespace naam die in de WSDL wordt gebruikt.
  • endpointInterface: de Java interface definitie voor de webservice. Deze verwijst met volledig pad naar de interface definitie, zie voorbeeld en beschrijving hierna.

Er wordt gebruik gemaakt van een Interface voor de webservice. Deze is nodig voor de clients die gebruik gaan maken van de webservice. Zie hieronder een voorbeeld:

@WebService(targetNamespace = "http://biz.org/wsdl")
public interface DepartmentService {
    public ReturnStatus create(String name,String address, int budget) ;
    public List<Department> list(int first, int max);
    public Department find(int id);
    public ReturnStatus delete(int id);
    public ReturnStatus update(long id, String name,String address,int budget);
}

Na deployment in een JEE container wordt deze dus automatisch als webservice gepubliceerd met de WSDL definitie zoals in voorgaande WSDL paragraaf beschreven.
In de opstart log van TomEE is het volgende te zien :


INFO: Webservice(wsdl=http://localhost:8082/employeesSOAPH/webservices/DepartmentServiceWS, qname={http://biz.org/wsdl}DepartmentServiceWS) --> Ejb(id=DepartmentServiceWS)

De WSDL definitie kan via de volgende url in de browser worden opgevraagd, waarna we de WSDL zien zoals in voorgaande WSDL paragraaf getoond.

http://localhost:8082/employeesSOAPH/webservices/DepartmentServiceWS?wsdl

SOAP Webservice Client

Hieronder het voorbeeld van de aanroep van de hiervoor beschreven Webservice implementatie met de gespecificeerde onderdelen zoals de serviceName, namespace.
Nadat de service is gecreëerd, wordt met de aanroep van de getPort operatie de verbinding met het Webservice endpoint verkregen. Daarmee kunnen de operaties van de Webservice gewoon worden aangeroepen alsof het een lokale Java class is.

Service service = null;
try {
service = Service.create(
new URL(baseURL + "/webservices/DepartmentServiceWS?wsdl"),
new QName("http://biz.org/wsdl", "DepartmentServiceWS"));
	DepartmentService department = service.getPort(DepartmentService.class);
	ReturnStatus sts = department.update(Integer.parseInt(departmentId), name, address, Integer.parseInt(budget));
} catch (MalformedURLException e) {
e.printStackTrace();
}
This entry was posted in JEE, Middleware and tagged , , . Bookmark the permalink.

Geef een reactie

Je e-mailadres wordt niet gepubliceerd.

De volgende HTML tags en attributen zijn toegestaan: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>