Com o Java™ API for XML-Based Web Services (JAX-WS), é possível enviar anexos binários como imagens ou arquivos juntamente com pedidos de serviços da Web. O JAX-WS inclui suporte para transmissão otimizada de dados binários conforme especificado
pela especificação SOAP MTOM (Message Transmission Optimization Mechanism).
Sobre Esta Tarefa
O JAX-WS suporta o uso do SOAP MTOM (Message Transmission Optimized
Mechanism) para enviar dados de anexo binário. Ativando o MTOM, é
possível enviar e receber dados binários de forma otimizada sem incorrer no custo da
codificação de dados necessária para incorporar os dados binários em um documento XML.
O servidor de aplicativos suporta o envio de anexos utilizando MTOM apenas
para aplicativos JAX-WS. Esse produto também oferece a capacidade de fornecer anexos com mensagens SOAP da Segurança de Serviços da Web usando os novos padrões MTOM e XOP.
Os aplicativos JAX-WS
podem enviar dados binários como dados codificados com base64 ou hexBinary contidos
no documento XML. No entanto, para tirar proveito das otimizações fornecidas por
MTOM, ative MTOM para enviar os dados base64 binários como anexos contidos fora
do documento XML. A otimização de MTOM não é ativada por padrão. Os aplicativos JAX-WS necessitam da configuração separada dos artefatos de
cliente e do servidor para ativar o suporte MTOM.
Procedimento
- Desenvolva artefatos Java para o seu aplicativo JAX-WS que inclua um esquema XML ou arquivo Web Services Description Language (WSDL) que representa os dados do seu aplicativo de serviços da Web que inclui um anexo binário.
- Se você estiver iniciando com um arquivo WSDL, desenvolva artefatos Java
a partir de um arquivo WSDL usando o comando wsimport para gerar
os artefatos portáveis JAX-WS necessários.
- Se você estiver iniciando com componentes JavaBeans, desenvolva artefatos Java para aplicativos JAX-WS e
gere, opcionalmente, um arquivo WSDL usando o comando wsgen. O esquema
XML ou arquivo WSDL inclui uma definição de elemento xsd:base64Binary
ou xsd:hexBinary para os dados binários.
- Você também pode incluir o atributo
xmime:expectedContentTypes no elemento para afetar o mapeamento por JAXB.
- Ative o MTOM na classe de implementação do terminal
usando um dos seguintes métodos:
- Use a anotação @MTOM no terminal.
Para ativar o MTOM em um terminal, utilize a anotação @MTOM (javax.xml.ws.soap.MTOM)
no terminal. A anotação @MTOM tem dois parâmetros, enabled e threshold. O parâmetro enabled tem um valor booleano e indica se MTOM
está ativado para o terminal JAX-WS. O parâmetro threshold
tem um valor inteiro que deve ser maior ou igual a zero. Quando o MTOM estiver ativado, quaisquer dados binários cujo tamanho, em bytes, exceder
o valor do limite, for codificado por XML-binary Optimized Packaging (XOP)
ou enviado como um anexo. Quando o tamanho da mensagem for menor que o valor do
limite, a mensagem será colocada em sequencia no documento XML como dados
base64 ou hexBinary.
O seguinte fragmento de exemplo ilustra
a inclusão da anotação @MTOM para que MTOM seja ativado para o terminal JAX-WS
MyServiceImpl
e especifique um valor de limite de 2048 bytes:
@MTOM(enabled=true, threshold=2048)
@WebService
public class MyServiceImpl {
...
}
Além disso, é possível usar a anotação @BindingType
(javax.xml.ws.BindingType) em uma classe de implementação de terminal para especificar que o
terminal suporte um dos tipos de ligação MTOM, para que as mensagens de
resposta sejam ativadas por MTOM. A classe javax.xml.ws.SOAPBinding define
duas constantes diferentes,
SOAP11HTTP_MTOM_BINDING e
SOAP12HTTP_MTOM_BINDING que
podem ser usadas para o valor da anotação @BindingType; por exemplo:
// Este exemplo serve para o SOAP versão 1.1.
@BindingType(value = SOAPBinding.SOAP11HTTP_MTOM_BINDING)
@WebService
public class MyServiceImpl {
...
}
// Este exemplo serve para o SOAP versão 1.2.
@BindingType(value = SOAPBinding.SOAP12HTTP_MTOM_BINDING)
@WebService
public class MyServiceImpl {
...
}
A presença e o valor de uma anotação @MTOM substitui o
valor da anotação @BindingType. Por exemplo, se o @BindingType
indicar que MTOM está ativado, mas uma anotação @MTOM estiver presente com
um valor enabled de false,
o MTOM não está ativado.
- Use os elementos de descritor de implementação <enable-mtom> e
<mtom-threshold>.
É possível usar os elementos
<enable-mtom> e
<mtom-threshold>
dentro do elemento
<port-component> no descritor de implementação
webservices.xml como uma alternativa ao uso da anotação @MTOM
na classe de implementação do terminal em serviço; por exemplo:
<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>
Evitar Problemas: Os elementos do descritor de implementação têm precedência
sobre os atributos correspondentes na anotação MTOM. Por exemplo, se o atributo
enabled
estiver configurado como
true na anotação, mas o elemento
<enable-mtom>
estiver configurado como
false no arquivo
webservices.xml,o MTOM não está ativado para o terminal correspondente.
gotcha
- Ative o MTOM no cliente para otimizar
as mensagens binárias que são enviadas do cliente para o servidor. Use um dos seguintes métodos para ativar o MTOM no cliente:
- Ative o MTOM em um cliente Dispatch.
Nota: Para um cliente de despacho, o aplicativo cliente precisa construir uma mensagem SOAP em formato
otimizado.
Os exemplos a seguir
usam o SOAP versão 1.1.
O primeiro método usa SOAPBinding.setMTOMEnabled();
por exemplo:
SOAPBinding binding = (SOAPBinding)dispatch.getBinding();
binding.setMTOMEnabled(true);
O segundo método
usa Service.addPort; por exemplo:
Service svc = Service.create(serviceName);
svc.addPort(portName,SOAPBinding.SOAP11HTTP_MTOM_BINDING,endpointUrl);
O
terceiro método usa MTOMFeature; por exemplo:
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);
- Ative o MTOM em um cliente de Proxy Dinâmico.
// Crie um BindingProvider bp a partir de uma porta de proxy.
Service svc = Service.create(serviceName);
MtomSample proxy = svc.getPort(portName, MtomSample.class);
BindingProvider bp = (BindingProvider) proxy;
//Ativar o MTOM usando o SOAPBinding.
MtomSample proxy = svc.getPort(portName, MtomSample.class);
BindingProvider bp = (BindingProvider) proxy;
SOAPBinding binding = (SOAPBinding) bp.getBinding();
binding.setMTOMEnabled(true);
//Ou você pode ativar o MTOM com o MTOMFeature.
MTOMFeature mtom = new MTOMFeature();
MtomSample proxy = svc.getPort(portName, MtomSample.class, mtom);
- Ative o MTOM no cliente usando a anotação @MTOM; por
exemplo:
public class MyClientApplication {
// Ativar o MTOM para uma injeção de recurso port-comonent-ref.
@MTOM(enabled=true, threshold=1024)
@WebServiceRef(MyService.class)
private MyPortType myPort;
...
}
- Ative o MTOM no cliente usando elementos do descritor de implementação
dentro de um elemento port-component-ref; por exemplo:
<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>
Evitar Problemas: Os elementos do descritor de implementação têm precedência
sobre os atributos correspondentes na anotação MTOM. Por exemplo, se o atributo
enabled
estiver configurado como
true na anotação, mas o elemento
<enable-mtom>
estiver configurado como
false na entrada do descritor de implementação
para o service-ref do cliente, o MTOM não está ativado para essa referência de
serviço.
gotcha
Resultados
Você desenvolveu um servidor de serviços da Web JAX-WS e aplicativo cliente que, de maneira otimizada, envia e recebe dados binários usando MTOM.
Exemplo
O exemplo a seguir ilustra a ativação de suporte MTOM em ambos, no cliente de serviços da Web e no terminal do servidor ao iniciar com um arquivo WSDL.
- Localize o arquivo WSDL que contém um elemento
xsd:base64Binary. O exemplo a seguir é uma parte de um arquivo WSDL que contém um 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>
- Execute o comando wsimport a partir do diretório
app_server_root\bin\
no arquivo WSDL para gerar um conjunto de artefatos portáteis JAX-WS.
Dependendo do valor
expectedContentTypes contido no arquivo WSDL, os artefatos JAXB gerados estão no tipo Java, conforme
descrito na seguinte tabela:
Tabela 1. Mapeamento
de Tipo MIME e de Tipo Java. Descreve o mapeamento entre tipos MIME e 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 |
- Use os artefatos JAXB da mesma maneira que em qualquer outro aplicativo JAX-WS. Utilize
esses beans para enviar os dados binários a partir das APIs do cliente
Dispatch e de Proxy Dinâmico.
- Ative o MTOM em um cliente Dispatch.
//Crie a instância Dispatch.
JAXBContext jbc = JAXBContext.newInstance("org.apache.axis2.jaxws.sample.mtom");
Dispatch<Object> dispatch = svc.createDispatch(portName, jbc, Service.Mode.PAYLOAD);
//Ative o MTOM.
SOAPBinding binding = (SOAPBinding) dispatch.getBinding();
binding.setMTOMEnabled(true);
- Ative o MTOM em um cliente de Proxy Dinâmico.
//Crie a instância de Proxy Dinâmico.
Service svc = Service.create(serviceName);
MtomSample proxy = svc.getPort(portName, MtomSample.class);
//Ative o MTOM.
BindingProvider bp = (BindingProvider) proxy;
SOAPBinding binding = (SOAPBinding) bp.getBinding();
binding.setMTOMEnabled(true);
Agora que você ativou o cliente
JAX-WS para MTOM, as mensagens enviadas ao servidor possuem MTOM ativado.
No entanto, para o servidor responder ao cliente
usando MTOM, você deve ativar o MTOM no terminal.
- Ative o MTOM na classe de implementação do
terminal.
@MTOM(enabled, threshold=4096)
@WebService (endpointInterface="org.apache.axis2.jaxws.sample.mtom.MtomSample")
public class MtomSampleService implements MtomSample {
....
}
A classe jaxax.xml.ws.SOAPBinding possui um membro
estático para cada um dos tipos de ligação suportados. Inclua SOAP11HTTP_MTOM_BINDING ou
SOAP12HTTP_MTOM_BINDING como o valor para a anotação @BindingType. Esse valor permite que todas as respostas do servidor tenham o MTOM ativado.
Ao ativar o MTOM no servidor e no cliente, os dados binários que
representam o anexo serão incluídos como um anexo MIME (Multipurpose Internet
Mail Extensions) na mensagem SOAP.
Sem o
MTOM, os mesmos dados são codificados no formato que descreve o esquema
XML, codificação base64 ou hexadecimal, e são incluídos sequencialmente
no documento XML.
Este exemplo ilustra uma mensagem SOAP
versão 1.1 ativada pelo MTOM com um anexo. Os atributos
type e
content-type possuem um valor,
application/xop+xml, que indica que a mensagem foi otimizada
com êxito utilizando o XOP (XML-binary Optimized Packaging)
quando MTOM foi ativado. Este exemplo demonstra como será a aparência da mensagem
otimizada na conexão com MTOM ativado.
... 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>
… binary data goes here …
--MIMEBoundaryurn_uuid_0FE43E4D025F0BF3DC11582467646812--
Por outro lado,
este exemplo demonstra uma mensagem SOAP versão 1.1 na conexão sem MTOM
ativado. Os dados binários são incluídos
no corpo da mensagem SOAP e a mensagem SOAP não é otimizada.
... 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 obter informações adicionais, consulte a seção Amostras
do Centro de Informações que inclui uma amostra que demonstra o uso do MTOM com os serviços da Web
JAX-WS.