Apache Axis2: AXIOM – das neue Objektmodell für XML-Verarbeitung
Kommentare

Web Service mit AXIOM
Hat man sich mit AXIOM vertraut gemacht, kann man schon Web Services direkt mit AXIOM entwickeln und aufrufen. In diesem Fall wird kein Data-Binding-Werkzeug für die Konvertierung

Web Service mit AXIOM

Hat man sich mit AXIOM vertraut gemacht, kann man schon Web Services direkt mit AXIOM entwickeln und aufrufen. In diesem Fall wird kein Data-Binding-Werkzeug für die Konvertierung zwischen XML und Objekt eingesetzt. Das Programmiermodell ähnelt sehr stark dem aus Axis 1.x, wenn man dort statt eines RPC-Providers einen MSG-Provider verwendet hätte. Während in Axis 1.x die DOM-Klasse Element (bzw. Document) oder die SAAJ-Klasse SOAPBodyElement (bzw. SOAPEnvelope) als Parameter oder Rückgabe verwendet werden, benutzt Axis2 die AXIOM-Klasse OMElement. Für diesen Zweck liefert Axis2 auch bereits fertige Implementierungen von Message-Receivern mit, die direkt eingesetzt werden können.

  • RawXMLINOnlyMessageReceiver: Dieser Receiver soll für Operationen eingesetzt werden, die dem MEP IN-ONLY entsprechen. Das bedeutet, dass für den Aufruf keine Antwort erwartet wird. Die Signatur der Methoden, die von diesem Receiver aufgerufen werden sollen, muss immer so aussehen: void > (OMElement request).
  • RawXMLINOutMessageReceiver: Dieser Receiver implementiert das gängige IN-OUT-MEP. Daher muss der Receiver nach Aufruf der Geschäftslogik dafür sorgen, die Rückgabe der Servicemethode in einem Response Envelope zu verpacken, eine neue Axis Engine zu erzeugen und die Response mithilfe der Engine zu verschicken. Die Signatur der Methoden, die von diesem Receiver aufgerufen werden sollen, muss entsprechend so aussehen: OMElement > (OMElement request).
  • RawXMLINOutAsyncMessageReceiver: Dieser Receiver ist für Kommunikationen geeignet, die ebenfalls Response-Nachrichten erwarten, jedoch nicht synchron, sondern asynchron verschickt werden sollen. Die entsprechenden Methoden müssen auch folgende Signatur besitzen: OMElement > (OMElement request).

Dank der bereits mitgelieferten Message-Receiver gestaltet sich die Aufgabe, einen Web Service direkt mit AXIOM zu entwickeln, sehr einfach. Die Receiver bzw. die AxisEngine kümmern sich bereits um das Dispatching und Entpacken von SOAP Envelope, sodass die Servicemethode lediglich mit dem Inhalt von SOAP Body (Nutzdaten bzw. Payload) in der Request- bzw. Response-Nachricht zu tun hat. Da das AXIOM API lesende und schreibende Zugriffe erlaubt, kann man damit zum einen Daten aus der Request-Nachricht auslesen und zum anderen das Ergebnis der Logikausführung in die Response-Nachricht hinein schreiben. In Listing 4 wird eine AXIOM-basierte Serviceimplementierung, die die erwähnten MEPs benutzt, der passende Deployment-Deskriptor in Listing 5 gezeigt.

Listing 4: Serviceimplementierung mit RawXMLMessageReceiver (AxisHotelService.java)
---------------------------------------------------------------------
public class AxisHotelService {
 public void registerHotel(OMElement registerHotelrequestElement){
   OMElement hotelElement = 
       registerHotelrequestElement.getFirstElement();
   String manager = hotelElement
       .getFirstChildWithName(new QName("manager")).getText();
   String id = hotelElement.getAttributeValue(new QName("id"));
   String name = hotelElement
       .getFirstChildWithName(new QName("name")).getText();
   Hotel hotel = new Hotel(id, name, manager);
   addHotel(hotel);
 }

 public OMElement getHotelDetail
  (OMElement getHotelRequestElement) {
   OMElement idElement = getHotelRequestElement.getFirstElement();
   String id = idElement.getText();
   Hotel hotel = retrieveHotel(id);
   OMFactory fac = OMAbstractFactory.getOMFactory();
   OMNamespace ns = 
       fac.createOMNamespace("http://www.axishotel.com/", "ah");
   OMElement responseElem = 
       fac.createOMElement("GetHotelDetailResponse", ns);
   OMElement hotelElem = 
       fac.createOMElement("hotel", null, responseElem); 
   hotelElem.addAttribute(fac.createOMAttribute("id", null, id));
   OMElement nameElem = 
       fac.createOMElement("name", null, hotelElem);
   nameElem.setText(hotel.getName());
   hotelElem.addChild(nameElem);
   OMElement managerElem = 
       fac.createOMElement("manager", null, hotelElem);
   managerElem.setText(hotel.getManager());
   hotelElem.addChild(managerElem);        
   return responseElem;
 }
}
Listing 5: Deployment-Deskriptor mit RawXMLMessageReceiver (service.xml)
--------------------------------------------------------------------------------

    This is a sample Web Service using RawXMLMessageReceivers
  
    com.axishoteö.AXIOM.service.AxisHotelService
  urn:getHotelDetailurn:registerHotel

Auch Service-Clients lassen sich vollständig mit dem AXIOM API entwickeln, unabhängig davon, ob die Service-Implementierung über RawXMLMessage­Receivers angeschlossen ist. Auch für POJO Services können Service-Clients mit AXIOM­ implementiert werden, solange diese das von WSDL beschriebene Nachrichtenformat liefert. Wie auf der Serverseite konzentriert man sich nur auf die wirklichen Nutzdaten. Das Verpacken der Nutzdaten im SOAP Envelope wird von Axis2 übernommen. Listing 6 zeigt einen Service-Client für den obigen Hotelservice. Zu beachten ist, dass aufgrund der unterschiedlichen MEPs der beiden Methoden der Request mit ServiceClient.fireAndForget() oder mit ServiceClient.sendAndReceive() verschickt wird.

Listing 6: Service-Client (AxisHotelServiceClient.java)
----------------------------------------------------------------------
public class AxisHotelServiceClient {
  private static EndpointReference targetEPR = 
    new EndpointReference
      ("http://localhost:8080/axis2/services/AXIOMservice");
  
  public static void main(String[] args) throws Exception {
    OMElement registerHotelRequest = createRegisterHotelPayload();
    ServiceClient serviceClient = new ServiceClient();
    Options options = new Options();
    options.setAction("urn:registerHotel");
    serviceClient.setOptions(options);
    options.setTo(targetEPR);
    serviceClient.fireAndForget(registerHotelRequest);
    Thread.sleep(500);
    OMElement getHotelDetailRequest = createGetHotelPayload();
    options.setAction("urn:getHotelDetail");
    serviceClient = new ServiceClient();
    serviceClient.setOptions(options);
    OMElement detailEl = 
      serviceClient.sendReceive(getHotelDetailRequest);
    System.out.println(detailEl);
  }

  private static OMElement createRegisterHotelPayload() {
    OMFactory fac = OMAbstractFactory.getOMFactory();
    OMNamespace ns = 
      fac.createOMNamespace("http://www.axishotel.com/", "ah");
    OMElement registerHotelElem = 
      fac.createOMElement("RegisterHotelRequest", ns);
    OMElement hotelElem = 
      fac.createOMElement("hotel", null, registerHotelElem);
    hotelElem
      .addAttribute(fac.createOMAttribute("id", null, "100"));
    OMElement nameElem = 
      fac.createOMElement("name", null, hotelElem);
    nameElem.setText("Axis Hotel");
    hotelElem.addChild(nameElem);
    OMElement managerElem = 
      fac.createOMElement("manager", null, hotelElem);
    managerElem.setText("Duke");
    hotelElem.addChild(managerElem);
    return registerHotelElem;
  }
  
  private static OMElement createGetHotelDetailPayload() {
    OMFactory fac = OMAbstractFactory.getOMFactory();
    OMNamespace ns = 
      fac.createOMNamespace("http://www.axishotel.com/", "ah");
    OMElement getHotelDetailElem = 
      fac.createOMElement(     "GetHotelDetailRequest", ns);
    OMElement idElem = 
      fac.createOMElement("id", null, getHotelDetailElem);
    idElem.setText("100");
    return getHotelDetailElem;
  }
}
Schlussbetrachtung

AXIOM hat von anderen existierenden APIs gelernt und verkörpert nun die Vorteile ereignisbasierter und baumbasierter APIs in einem. Damit hat man die Möglichkeit, die beste Balance zwischen Performance und Benutzerkomfort zu erzielen. Durch die vielfältige und flexible Schnittstelle sowohl nach innen als auch nach außen ist AXIOM nicht nur universell einsetzbar, sondern auch für besonders komplexe Anwendungsfälle bestens geeignet. Mit AXIOM baut Axis2 auf eine sehr solide Grundlage, womit gleichzeitig eine wichtige Voraussetzung erfüllt ist, um dem Namen „Web Service Engine der nächsten Generation“ gerecht zu werden.

Dapeng Wang ist freiberuflicher Systemarchitekt, Trainer und Buchautor. Sein Schwerpunkt liegt auf Design und Implementierung von komplexen Enterprise-Applikationen mit Java EE- und Web-Service-Technologien. Kontakt: Wang.Dapeng[at]gmx.net.
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -