[jbossws-issues] [JBoss JIRA] Commented: (JBWS-3074) @XmlMimeType breaks DataHandler

Richard Opalka (JIRA) jira-events at lists.jboss.org
Thu Jul 1 05:08:46 EDT 2010


    [ https://jira.jboss.org/browse/JBWS-3074?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12537611#action_12537611 ] 

Richard Opalka commented on JBWS-3074:
--------------------------------------

   JBossWS Native JAX-WS MTOM/XOP support is handled in JAXB runtime JBossWS Native delegates to.
Thus issue your are facing is JAXB un/marshalling issue and not JBossWS Native issue.
   In the future all your JBossWS Native JAX-WS un/marshalling questions can be posted directly
to JAXB development team (https://jaxb.dev.java.net/).
   However I spent some time to help you with this issue and here are my investigations:

Before starting please have a look to:

JAXB 2.2 javadoc for the following annotations:
 * @javax.xml.bind.annotation.XmlMimeType
 * @javax.xml.bind.annotation.XmlInlineBinaryData

JAX-WS 2.2 javadoc for the following annotations:
 * @javax.xml.ws.BindingType
 * @javax.xml.ws.soap.MTOM
 * @javax.xml.ws.soap.MTOMFeature

The following objects can be sent as MTOM/XOP attachments:
 * byte[]
 * java.awt.Image
 * javax.xml.transform.Source
 * javax.activation.DataHandler

Enabling MTOM on JAX-WS endpoint can be achieved:
 * either by declaring @MTOM
 * or by declaring @BindingType(value = "http://schemas.xmlsoap.org/wsdl/soap/http?mtom=true")

Enabling MTOM on JAX-WS client can be achieved:
 * either ((SOAPBinding)((BindingProvider)port).getBinding()).setMTOMEnabled(true) on already created proxy
 * or service.getPort(MTOMEndpoint.class, new MTOMFeature(true)) for proxies being created

If you don't specify @XmlMimeType on getter or
if you specify both @XmlMimeType and @XmlInlineBinaryData on getter
the attachment object will always be inlined on the wire.

If you specify only @javax.xml.bind.annotation.XmlMimeType on getter
the attachment object will always be sent as MIME attachment on the wire.

@XmlMimeType is used in JAXB schema generator
and adds xmlmime:expectedContentTypes to WSDL. Here's example:
---
<?xml version="1.0" encoding="UTF-8"?>
<definitions ...>
  <types>
    <xs:schema targetNamespace="SOME_NS" version="1.0" xmlns:tns="SOME_NS" xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:element name="echoDataHandler" nillable="true" type="tns:dataRequest"/>
      <xs:complexType name="dataRequest">
        <xs:sequence>
          <xs:element minOccurs="0" name="dataHandler" ns1:expectedContentTypes="text/plain" type="xs:base64Binary" xmlns:ns1="http://www.w3.org/2005/05/xmlmime"/>
      </xs:sequence>
    </xs:complexType>
    ...
  </types>
  ...
</definitions>
---

When there's a JAX-WS handler processing SOAP Body of the SOAP Envelope 
registered with JAX-WS client or endpoint the MTOM attachment is always inlined to the SOAP message at runtime
regardless of the fact it was inlined or sent as MIME attachment on the wire.
IOW JAX-WS handler always see MTOM attachments as inlined base64Binary or hexBinary.

Conclusion:

JAXB un/marshalling violates MTOM/XOP specifications and generates invalid MTOM/XOP messages.
JAXB should generate in XML schema and process xmlmime:contentType attribute on XML elements wrapping binary data
(regardless of the fact they are sent as inlined base64Binary or MIME attachments - see MTOM/XOP specifications).

Example of broken message being exchanged:
---
<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
  <env:Header/>
  <env:Body>
    <ns1:echoDataHandler xmlns:ns1="http://org.jboss.ws/xop/doclit">
      <dataHandler>RGF0YUhhbmRsZXJSb3VuZHRyaXA=</dataHandler> <!-- here content type information is lost because of missing xmlmime:contentType attribute -->
    </ns1:echoDataHandler>
  </env:Body>
</env:Envelope>
---

When attachment that is un/marshalled by JAXB runtime is inlined
the content type information is always lost (see generated schema).

When attachment that is un/marshalled by JAXB runtime was sent as MIME multipart
the content type information is obtained from MIME header.

When there's JAX-WS handler processing SOAP Body of the SOAP Envelope
registered with JAX-WS client or endpoint then JAXB un/marshalling process
will always see inlined base64Binary or hexBinary and thus it will always
result in content type information being lost.

Suggestions:

To don't lose content type information the following suggestions/workarounds come to my mind:
 * don't use JAX-WS handlers to read SOAP body if it's not necessary
 * don't force inlining of attachments
 * use different data structures and keep content type information separately and don't rely on JAXB un/marshalling magics for DataHandler objects

> @XmlMimeType breaks DataHandler
> -------------------------------
>
>                 Key: JBWS-3074
>                 URL: https://jira.jboss.org/browse/JBWS-3074
>             Project: JBoss Web Services
>          Issue Type: Bug
>      Security Level: Public(Everyone can see) 
>          Components: jbossws-native
>    Affects Versions: jbossws-native-3.2.1
>            Reporter: Martin Vecera
>            Assignee: Richard Opalka
>            Priority: Critical
>             Fix For: jbossws-native-3.4.0
>
>         Attachments: webservice_mtom2.tar.bz2
>
>
> I have a test client that sends WS attachment using DataHandler like this:
> MTOMEndpoint mtomEndpoint = getEndpointPort();
> DataHandler send = new DataHandler(new FileDataSource(PNG_FILE));
> DHRequest request = new DHRequest(send);
> DHResponse response = mtomEndpoint.echoData(request);
> DataHandler recv = response.getDataHandler();
> The server WS just sends back what it receives:
> byte[] echoFile = StreamUtils.readStream((InputStream)(request.getDataHandler().getContent()));
> DataHandler o = new DataHandler(new ByteArrayInputStream(echoFile), request.getDataHandler().getContentType());
> return new DHResponse(o);
> The issue is in DHRequest and DHResponse classes I use. They are simple classes:
> @XmlType(name = "dataRequest", namespace = "http://org.jboss.ws/xop/doclit")
> public class DHRequest {
>   private DataHandler dataHandler;
>   public DHRequest() { }
>   public DHRequest(DataHandler dataHandler) {
>     this.dataHandler = dataHandler;
>   }
> //  @XmlMimeType("image/png")
>   public DataHandler getDataHandler() {
>     System.out.println(dataHandler.getContentType());
>     return dataHandler;
>   }
>   public void setDataHandler(DataHandler dataHandler) {
>     this.dataHandler = dataHandler;
>   }
> }
> DHResponse is the same if you replace Reuest with Response.
> Without setting the @XmlMimeType annotation everything works and the message on the server side looks like this:
> <env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'><env:Header></env:Header><env:Body><ns2:echoDataResponse xmlns:ns2="http://org.jboss.ws/xop/doclit"><return><dataHandler> ... Base64 encoded data ... </dataHandler></return></ns2:echoDataResponse></env:Body></env:Envelope>
> The DataHandler's content type on the client side (see the System.out.println) is image/png in the request and application/octet-stream in the response.
> On the server side it is application/octet-stream in both cases.
> No matter what I set in @XmlMimteType, it always broke. I tried application/octet-stream, text/plain and image/png. The thing is that whenever I set a mime type explicitly, the message stop being Base64 encoded. Instead it is a message with a binary attachment. The following is when DHResponse used application/octet-stream:
> ------=_Part_2_74198202.1277739135119
> Content-Type: application/xop+xml; type="text/xml"
> Content-Transfer-Encoding: 8bit
> Content-ID: <rootpart at ws.jboss.org>
> <env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'><env:Header></env:Header><env:Body><ns2:echoDataResponse xmlns:ns2="http://org.jboss.ws/xop/doclit"><return><dataHandler><xop:Include xmlns:xop="http://www.w3.org/2004/0
> 8/xop/include" href="cid:dataHandler-75243ed1-23b7-4d2a-9ae6-aa2cb84c8e8f at ws.jboss.org"/></dataHandler></return></ns2:echoDataResponse></env:Body></env:Envelope>
> ------=_Part_2_74198202.1277739135119
> Content-Type: application/octet-stream
> Content-Transfer-Encoding: binary
> Content-Id: <dataHandler-75243ed1-23b7-4d2a-9ae6-aa2cb84c8e8f at ws.jboss.org>
> ... binary scarp ...
> ------=_Part_2_74198202.1277739135119--
> Attached is a sample ESB quickstart reproducing the issue. Please note that this is a regression in SOA-P. What is the expected behavior? How it should be used?

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the jbossws-issues mailing list