Search code examples
javaweb-servicesjaxbjax-ws

wsimport tool is converting DataHandler type byte[] in the generated client code


I have a simple WebService developed using JAXWS. I need to upload/download some Files. I have created a Class FileItem with DataHandler a property. The service is running fine.

But when I generated the client stubs using wsimport tool, the FileItem class is having byte[] type property instead of DataHandler type.

How can I customize this behavior so that the generated code also have same DataHandler Type in generated client code?


Solution

  • Short Answer

    If you specify an xmime:expectedContentTypes on the element that is anything except: image/gif, image/jpeg, text/xml, or application/xml then the generated property will be of type DataHandler.


    Long Answer

    From Section H.2.1.1 Binding Known Media Type of the JAXB 2.2 specification, below are how mime types correspond to the generated Java types.

    MIME Type              Java Type
    ---------              -------------
    image/gif              java.awt.Image
    image/jpeg             java.awt.Image
    text/xml               javax.xml.transform.Source
    application/xml        javax.xml.transform.Source
    any other mime type    javax.activation.DataHandler
    

    XML Schema

    Below is an XML schema that has many elements of type base64Binary, most of them are qualified with xmime:expectedContentTypes so that we can see the impact on the resulting class generation.

    <?xml version="1.0"?>
    <xsd:schema
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:xmime="http://www.w3.org/2005/05/xmlmime"
        xmlns="http://www.example.com"
        targetNamespace="http://www.example.com">
        <xsd:element name="root">
            <xsd:complexType>
                <xsd:sequence>
                    <xsd:element minOccurs="0" name="default" type="xsd:base64Binary"/>
                    <xsd:element minOccurs="0" name="imageGif" type="xsd:base64Binary" xmime:expectedContentTypes="image/gif"/>
                    <xsd:element minOccurs="0" name="imageJpeg" type="xsd:base64Binary" xmime:expectedContentTypes="image/jpeg"/>
                    <xsd:element minOccurs="0" name="textXml" type="xsd:base64Binary" xmime:expectedContentTypes="text/xml"/>
                    <xsd:element minOccurs="0" name="applicationXml" type="xsd:base64Binary" xmime:expectedContentTypes="application/xml"/>
                    <xsd:element minOccurs="0" name="anythingElse" type="xsd:base64Binary" xmime:expectedContentTypes="anything/else"/>
                </xsd:sequence>
            </xsd:complexType>
        </xsd:element>
    </xsd:schema>
    

    Root(Generated Class)

    Below is the resulting generated class. The resulting property types are byte[], Image, Source, and DataHandler.

    package com.example;
    
    import java.awt.Image;
    import javax.activation.DataHandler;
    import javax.xml.bind.annotation.*;
    import javax.xml.transform.Source;
    
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "_default",
        "imageGif",
        "imageJpeg",
        "textXml",
        "applicationXml",
        "anythingElse"
    })
    @XmlRootElement(name = "root")
    public class Root {
    
        @XmlElement(name = "default")
        protected byte[] _default;
        @XmlMimeType("image/gif")
        protected Image imageGif;
        @XmlMimeType("image/jpeg")
        protected Image imageJpeg;
        @XmlMimeType("text/xml")
        protected Source textXml;
        @XmlMimeType("application/xml")
        protected Source applicationXml;
        @XmlMimeType("anything/else")
        protected DataHandler anythingElse;
    
    
        ...
    }