Metro und MTOM

MTOM aktivieren

Das Aktivieren von MTOM in Webservices ist mit dem Metro-Stack ziemlich einfach. Dazu ist nur die Annotation @MTOM erforderlich:

@WebService
@MTOM(enabled=true)
public class ServiceImpl {

 @WebMethod
 public byte[] getImageById(@WebParam(name = "id") final Integer id) {
  byte[] result;

  ...

  return result;
 }
}

Die Response enthält dann anstelle des Byte-Arrays eine Referenz auf die Daten, welche als Attachment übertragen werden.

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
 <S:Body>
  <ns2:getImageByIdResponse xmlns:ns2="http://ronnyfriedland.de/mtom">
   <return>
    <xop:Include href="cid:fa04ad63-7fd8-4107-9704-6e0840d7ff53@example.jaxws.sun.com"
     xmlns:xop="http://www.w3.org/2004/08/xop/include"/>
   </return>
  </ns2:getImageByIdResponse>
 </S:Body>
</S:Envelope>

Voraussetzung dafür ist allerdings, dass auf Client-Seite ebenfalls MTOM aktiviert ist. Sollte der Client mal kein MTOM verstehen, ist das auch kein Problem, denn der Server sendet dann die Response als inline Bytearray.

Den Content-Type für das Ergebnis kann man durch die Annotation XmlMimeType als Value angeben. Ein Beispiel für ein Jpeg Bild wäre wie folgt:

@XmlMimeType("image/jpg")

Weiterhin kann man die Größe der Response über den Parameter threshold (in Bytes) angeben, ab welcher Größe die Response als Attachment zurück gegeben werden soll. Unterhalb dieser Grenze wird die Response wie gehabt inline als Byte-Array zurück gegeben.

Das gesamte Beispiel der Serviceklasse gibt es hier:

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;

import javax.xml.bind.annotation.XmlMimeType;

import javax.xml.ws.soap.MTOM;

@WebService(targetNamespace = "http://ronnyfriedland.de/mtom", serviceName = "MTOMService")
@MTOM(enabled=true, threshold=2000)
public class ServiceImpl {

 @WebMethod
 public @XmlMimeType("image/jpg")
 byte[] getImageById(@WebParam(name = "id") final int id) {
  byte[] result;

  ...
  return result;
 }
}

Vergleich der Antwortzeiten MTOM vs. inline Bytearray

Meine Tests ergaben, dass die Übertragung einer 4MB Datei mit MTOM geringfügig schneller ist. Allerdings wird der Soap Envelope bei MTOM wesentlich schneller übertragen - danach erfolgt die Übertragung der Attachments. Der Client erhält also am Ende die Response schneller als bei der Übertragung als Inline Element.

Weitere Informationen gibt es u.a. im Metro Guide.