Con JAX-WS (API de Java™ para servicios web XML), puede enviar
adjuntos binarios como, por ejemplo, imágenes o archivos junto con las solicitudes de servicios web. JAX-WS añade soporte para la transmisión optimizada de datos binarios, tal como se indica en la especificación MTOM (SOAP Message Transmission Optimization Mechanism).
Acerca de esta tarea
JAX-WS soporta el uso del mecanismo MTOM (Message Transmission Optimized
Mechanism) de SOAP para el envío de datos adjuntos binarios. Al habilitar MTOM, puede enviar y recibir datos binarios de forma óptima sin asumir el coste de la codificación de datos necesaria para incluir los datos binarios en un documento XML.
El servidor de aplicaciones soporta el envío de adjuntos utilizando
el mecanismo MTOM sólo para aplicaciones JAX-WS. Este producto también proporciona la capacidad de ofrecer adjuntos con mensajes SOAP de Web Services Security utilizando los nuevos estándares del MTOM y XOP.
Las aplicaciones JAX-WS pueden enviar datos binarios como datos cifrados de base64 o hexBinary incluidos dentro del documento XML. Sin embargo, para sacar partido de las optimizaciones proporcionadas por el MTOM, habilite el mecanismo MTOM para enviar datos binarios base64 como adjuntos incluidos fuera del documento XML. La optimización MTOM no se habilita de manera predeterminada.
Las aplicaciones JAX-WS requieren una configuración separada de los artefactos del cliente y también del servidor para habilitar el soporte del MTOM.
Procedimiento
- Desarrolle artefactos Java para la aplicación JAX-WS que incluye un esquema XML o un archivo WSDL (Web Services Description Language) que representa los datos de la aplicación de servicios web que incluye un adjunto binario.
- Si va a empezar con un archivo WSDL, desarrolle los artefactos Java desde
un archivo WSDL utilizando el mandato wsimport para generar los artefactos portátiles JAX-WS necesarios.
- Si va a empezar con componentes JavaBeans, desarrolle artefactos Java para aplicaciones JAX-WS y,
de forma opcional, genere un archivo WSDL utilizando el mandato wsgen. El esquema XML
o el archivo WSDL incluye una definición de elemento xsd:base64Binary o xsd:hexBinary para los datos binarios.
- También puede incluir el atributo xmime:expectedContentTypes en el elemento para afectar a la correlación realizada por JAXB.
- Habilite MTOM en la clase de implementación de punto final mediante uno de los métodos siguientes:
- Utilice la anotación @MTOM en el punto final.
Para habilitar
MTOM en un punto final, utilice la anotación @MTOM (javax.xml.ws.soap.MTOM) en el punto final. La anotación @MTOM tiene dos parámetros enabled y threshold.
El parámetro enabled tiene un valor booleano e indica si se ha habilitado
MTOM para el punto final JAX-WS. El parámetro threshold
tiene un valor entero, que debe ser mayor que o igual a cero.
Cuando MTOM está habilitado,
los datos binarios cuyo tamaño, en bytes, sobrepasa el valor de umbral se codifican en
XOP (XML-binary Optimized Packaging - Empaquetado optimizado XML binario) o se envían
como un archivo adjunto. Cuando
el tamaño de mensaje es menor que el valor de umbral, el mensaje
se incorpora al documento XML como datos base64 o hexBinary.
El siguiente
fragmento de código de ejemplo ilustra la adición de la anotación
@MTOM para que MTOM esté habilitado para el punto final JAX-WS
MyServiceImpl
y especifica un valor de umbral de 2048 bytes:
@MTOM(enabled=true, threshold=2048)
@WebService
public class MyServiceImpl {
...
}
Además, puede utilizar la anotación
@BindingType (javax.xml.ws.BindingType) en una clase de implementación de punto final
para especificar que el punto final soporta uno de los tipos de enlace del MTOM de modo que
los mensajes de respuesta estén habilitados para MTOM. La clase javax.xml.ws.SOAPBinding define
dos constantes diferentes,
SOAP11HTTP_MTOM_BINDING y
SOAP12HTTP_MTOM_BINDING que puede utilizar para el valor de la anotación
@BindingType; por ejemplo:
// Este ejemplo es para SOAP versión 1.1.
@BindingType(value = SOAPBinding.SOAP11HTTP_MTOM_BINDING)
@WebService
public class MyServiceImpl {
...
}
// Este ejemplo es para SOAP versión 1.2.
@BindingType(value = SOAPBinding.SOAP12HTTP_MTOM_BINDING)
@WebService
public class MyServiceImpl {
...
}
La presencia y el valor de una anotación @MTOM altera temporalmente el valor de la anotación @BindingType. Por ejemplo, si @BindingType indica que
MTOM está habilitado pero no hay ninguna anotación @MTOM con un valor de false habilitado, es que
MTOM no estará habilitado.
- Utilice los elementos del descriptor de despliegue <enable-mtom> y <mtom-threshold>.
Puede utilizar los elementos
<enable-mtom>
y
<mtom-threshold> dentro del elemento
<port-component> en el
descriptor de despliegue webservices.xml como alternativa al uso de la anotación @MTOM en la clase de implementación
de punto final de servicio; por ejemplo:
<port-component>
<port-component-name>MyPort1</port-component-name>
<enable-mtom>true</enable-mtom>
<mtom-threshold>2048</mtom-threshold>
<service-impl-bean>
<servlet-link>MyPort1ImplBean</servlet-link>
</service-impl-bean>
</port-component>
Avoid trouble: Los elementos del descriptor de despliegue tienen prioridad sobre los atributos correspondientes en la anotación MTOM. Por ejemplo,
si el atributo
enabled se establece en
true en la anotación,
pero el elemento
<enable-mtom> se establece en
false en el archivo
webservices.xml, MTOM no se habilita para el punto
final correspondiente.
gotcha
- Habilite MTOM en el cliente para optimizar los mensajes binarios que se envían del cliente al servidor. Utilice uno de los métodos siguientes para habilitar MTOM en el cliente:
- Habilite el mecanismo MTOM en un cliente Dispatch.
Nota: En el caso de un cliente de asignación, la aplicación cliente necesita
construir un mensaje soap en formato optimizado.
Los ejemplos siguientes utilizan SOAP versión 1.1.
El primer
método utiliza SOAPBinding.setMTOMEnabled(); por ejemplo:
SOAPBinding binding = (SOAPBinding)dispatch.getBinding();
binding.setMTOMEnabled(true);
El segundo método utiliza Service.addPort; por ejemplo:
Service svc = Service.create(serviceName);
svc.addPort(portName,SOAPBinding.SOAP11HTTP_MTOM_BINDING,endpointUrl);
El tercer método utiliza MTOMFeature; por ejemplo:
MTOMFeature mtom = new MTOMFeature(true, 2048);
Service svc = Service.create(serviceName);
svc.addPort(portName, SOAPBinding.SOAP11_HTTP_BINDING, endpointUrl);
Dispatch<Source> dsp = svc.createDispatch(portName, Source.class, Service.Mode.PAYLOAD, mtom);
- Habilite el mecanismo MTOM en un cliente de proxy dinámico.
// Crear un bp BindingProvider desde un puerto de proxy.
Service svc = Service.create(serviceName);
MtomSample proxy = svc.getPort(portName, MtomSample.class);
BindingProvider bp = (BindingProvider) proxy;
//Habilitar MTOM utilizando SOAPBinding.
MtomSample proxy = svc.getPort(portName, MtomSample.class);
BindingProvider bp = (BindingProvider) proxy;
SOAPBinding binding = (SOAPBinding) bp.getBinding();
binding.setMTOMEnabled(true);
//O puede habilitar MTOM con MTOMFeature.
MTOMFeature mtom = new MTOMFeature();
MtomSample proxy = svc.getPort(portName, MtomSample.class, mtom);
- Habilite MTOM en el cliente utilizando la anotación @MTOM; por ejemplo:
public class MyClientApplication {
// Habilitar MTOM para una inyección de recursos port-comonent-ref.
@MTOM(enabled=true, threshold=1024)
@WebServiceRef(MyService.class)
private MyPortType myPort;
...
}
- Habilite MTOM en el cliente utilizando elementos de descriptor de despliegue en un elemento
port-component-ref; por ejemplo:
<service-ref>
<service-ref-name>service/MyPortComponentRef</service-ref-name>
<service-interface>com.example.MyService</service-ref-interface>
<port-component-ref>
<service-endpoint-interface>com.example.MyPortType</service-endpoint-interface>
<enable-mtom>true</enable-mtom>
<mtom-threshold>1024</mtom-threshold>
</port-component-ref>
</service-ref>
Avoid trouble: Los elementos del descriptor de despliegue tienen prioridad sobre los atributos correspondientes en la anotación MTOM. Por ejemplo, si el atributo
enabled se establece en
true en la anotación, pero el elemento
<enable-mtom> se establece en
false en la entrada del descriptor de despliegue para el service-ref del cliente, MTOM no está habilitado para dicha referencia de servicio.
gotcha
Resultados
Ha desarrollado una aplicación cliente y servidor de servicios web JAX-WS que envía y recibe de forma óptima datos binarios utilizando el MTOM.
Ejemplo
En el ejemplo siguiente se muestra la habilitación de soporte MTOM tanto en el cliente de servicios web y punto final del servidor cuando se empieza con un archivo WSDL.
- Localice el archivo WSDL que contiene un elemento xsd:base64Binary.
El ejemplo siguiente es un fragmento de un archivo WSDL que contiene un elemento xsd:base64Binary.
<types>
........
<xs:complexType name="ImageDepot">
<xs:sequence>
<xs:element name="imageData"
type="xs:base64Binary"
xmime:expectedContentTypes="image/jpeg"/>
</xs:sequence>
</xs:complexType>
........
</types>
- Ejecute el mandato wsimport desde el directorio raíz_servidor_aplic\bin\
para el archivo WSDL para generar un conjunto de artefactos JAX-WS portátiles.
En función del valor
expectedContentTypes incluido en el
archivo WSDL, los artefactos JAXB generados son del tipo Java, tal como se describe en la tabla siguiente:
Tabla 1. Correlación de un tipo MIME y un tipo Java. Describe la correlación entre tipos MIME y tipos Java. Tipo MIME |
Tipo Java |
image/gif |
java.awt.Image |
image/jpeg |
java.awt.Image |
text/plain |
java.lang.String |
text/xml |
javax.xml.transform.Source |
application/xml |
javax.xml.transform.Source |
*/* |
javax.activation.DataHandler |
- Utilice los artefactos JAXB como lo haría cualquier otra aplicación JAX-WS. Utilice estos
beans para enviar datos binarios desde ambas API, la Dispatch y la de cliente de proxy dinámico.
- Habilite el mecanismo MTOM en un cliente Dispatch.
//Crear la instancia de Dispatch.
JAXBContext jbc = JAXBContext.newInstance("org.apache.axis2.jaxws.sample.mtom");
Dispatch<Object> dispatch = svc.createDispatch(portName, jbc, Service.Mode.PAYLOAD);
//Habilitar el MTOM.
SOAPBinding binding = (SOAPBinding) dispatch.getBinding();
binding.setMTOMEnabled(true);
- Habilite el mecanismo MTOM en un cliente de proxy dinámico.
//Crear la instancia del proxy dinámico.
Service svc = Service.create(serviceName);
MtomSample proxy = svc.getPort(portName, MtomSample.class);
//Habilitar el MTOM.
BindingProvider bp = (BindingProvider) proxy;
SOAPBinding binding = (SOAPBinding) bp.getBinding();
binding.setMTOMEnabled(true);
Ahora que ya ha habilitado el cliente JAX-WS para el
MTOM, los mensajes enviados al servidor tienen el MTOM habilitado. Sin embargo, para que el servidor vuelva a responder al cliente mediante
MTOM, deberá habilitar MTOM en el punto final.
- Habilite MTOM en la clase de implementación
de punto final.
@MTOM(enabled, threshold=4096)
@WebService (endpointInterface="org.apache.axis2.jaxws.sample.mtom.MtomSample")
public class MtomSampleService implements MtomSample {
....
}
La clase jaxax.xml.ws.SOAPBinding tiene un miembro estático
para cada uno de los tipos de enlace soportados. Incluya SOAP11HTTP_MTOM_BINDING o
SOAP12HTTP_MTOM_BINDING como el valor para la anotación @BindingType. Este valor permite a todas las respuestas del servidor tener el MTOM habilitado.
Cuando habilite el MTOM en el servidor y el cliente, los datos binarios
que representan el adjunto se incluyen como un adjunto MIME (Multipurpose Internet Mail
Extensions) en el mensaje SOAP. Sin el MTOM,
los mismos datos se codifican en el formato que describe el esquema XML,
base64 o codificación hexadecimal, y se incluyen incorporados en el documento XML.
En este
ejemplo se muestra un mensaje de SOAP versión 1.1 habilitado para MTOM con un archivo adjunto. Los atributos
type y
content-type tienen el valor
application/xop+xml que indica que el mensaje se optimizó correctamente utilizando el paquete XOP (XML-Binary Optimized Packaging) cuando se habilitó el MTOM. Este ejemplo muestra cómo ve el mensaje optimizado en la comunicación con el mecanismo MTOM habilitado.
... other transport headers ...
Content-Type: multipart/related; boundary=MIMEBoundaryurn_uuid_0FE43E4D025F0BF3DC11582467646812;
type="application/xop+xml"; start="
<0.urn:uuid:0FE43E4D025F0BF3DC11582467646813@apache.org>"; start-info="text/xml"; charset=UTF-8
--MIMEBoundaryurn_uuid_0FE43E4D025F0BF3DC11582467646812
content-type: application/xop+xml; charset=UTF-8; type="text/xml";
content-transfer-encoding: binary
content-id:
<0.urn:uuid:0FE43E4D025F0BF3DC11582467646813@apache.org>
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<sendImage xmlns="http://org/apache/axis2/jaxws/sample/mtom">
<input>
<imageData>
<xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include"
href="cid:1.urn:uuid:0FE43E4D025F0BF3DC11582467646811@apache.org"/>
</imageData>
</input>
</sendImage>
</soapenv:Body>
</soapenv:Envelope>
--MIMEBoundaryurn_uuid_0FE43E4D025F0BF3DC11582467646812
content-type: text/plain
content-transfer-encoding: binary
content-id:
<1.urn:uuid:0FE43E4D025F0BF3DC11582467646811@apache.org>
... los datos binarios van aquí ...
--MIMEBoundaryurn_uuid_0FE43E4D025F0BF3DC11582467646812--
Por otro lado, este ejemplo muestra un mensaje
SOAP versión 1.1 en la comunicación con el mecanismo MTOM habilitado. Los datos binarios están
incluidos en el cuerpo del mensaje SOAP y el mensaje SOAP no está optimizado.
... other transport headers ...
Content-Type: text/xml; charset=UTF-8
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<sendImage xmlns="http://org/apache/axis2/jaxws/sample/mtom">
<input>
<imageData>R0lGADl ... more base64 encoded data ... KTJk8giAAA7</imageData>
</input>
</sendImage>
</soapenv:Body>
</soapenv:Envelope>
Para obtener información adicional, consulte la sección Ejemplos
del Information Center, que incluye un ejemplo donde se muestra el uso del MTOM con los servicios web JAX-WS.