JAXB unmarshal won't work with JDK 1.6

蹲街弑〆低调 提交于 2019-12-13 08:14:01

问题


Yes, this is a long boring posted question which is maybe very simple at the same time. :(

I just calling a SOAP WebService interface implemented with .NET platform from Java. After the data received, converting it to java objects using JAXB.Everything works well with JDK1.8, but failed with JDK1.6

I noticed that the unmarshalling process stopped at the GetBjxsDataResponse level. Namely I could successfully got an instance of GetBjxsDataResponse from the envelop body, but the getBjxsDataResult member of the instance is null.

Is this have something to do with the JAXB RI version? I'm a newbie to java world. Need your help! :)

NamespaceMapper.java

import com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper;

public class NamespaceMapper extends NamespacePrefixMapper {

    private static final String SOAP_PREFIX = "x";
    public static final String SOAP_URI = "http://schemas.xmlsoap.org/soap/envelope/";

    private static final String WS_PREFIX = "tem";
    public static final String WS_URI = "http://tempuri.org/";

    public static final String XMLSchema_URI = "http://www.w3.org/2001/XMLSchema";
    public static final String DIFFGR_URI = "urn:schemas-microsoft-com:xml-diffgram-v1";

    @Override
    public String getPreferredPrefix(String arg0, String arg1, boolean arg2) {
        if (SOAP_URI.equals(arg0))
            return SOAP_PREFIX;
        else if (WS_URI.equals(arg0))
            return WS_PREFIX;
        return arg1;
    }
}

Envelope.java

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "Envelope", namespace = NamespaceMapper.SOAP_URI)
@XmlAccessorType(XmlAccessType.FIELD)
public class Envelope {

    @XmlElement(name = "Header", namespace = NamespaceMapper.SOAP_URI, required = false)
    private EnvelopeHeader header;

    @XmlElement(name = "Body", namespace = NamespaceMapper.SOAP_URI)
    private EnvelopeBody body;

    public EnvelopeHeader getHeader() {
        return header;
    }

    public void setHeader(EnvelopeHeader header) {
        this.header = header;
    }

    public EnvelopeBody getBody() {
        return body;
    }

    public void setBody(EnvelopeBody body) {
        this.body = body;
    }
}

EnvelopeHeader.java

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(namespace = NamespaceMapper.SOAP_URI)
public class EnvelopeHeader {

}

EnvelopeBody.java

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(namespace = NamespaceMapper.SOAP_URI)
public class EnvelopeBody {

    @XmlAnyElement(lax = true)
    private Object method;

    public Object getMethod() {
        return method;
    }

    public void setMethod(Object method) {
        this.method = method;
    }
}

import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "GetBjxsDataResponse", namespace = NamespaceMapper.WS_URI)
@XmlAccessorType(XmlAccessType.FIELD)
public class GetBjxsDataResponse extends ResponseCommon {

    @XmlAccessorType(XmlAccessType.FIELD)
    private static class GetBjxsDataResult {

        @XmlRootElement
        @XmlAccessorType(XmlAccessType.FIELD)
        private static class Diffgram {

            @XmlAccessorType(XmlAccessType.FIELD)
            private static class NewDataSet {

                @XmlElement(name = "Table")
                private List<Object> lists;
            }

            @XmlElement(name = "NewDataSet")
            private NewDataSet newDataSet;
        };

        @XmlElement
        private Object schema;

        @XmlElement
        private Diffgram diffgram;
    };

    @XmlElement(name="GetBjxsDataResult")
    private GetBjxsDataResult getBjxsDataResult;

    @Override
    public Object getValuableData() {
        return getBjxsDataResult.diffgram.newDataSet.lists;
    }
}

ResponseCommon.java

import javax.xml.bind.annotation.XmlTransient;

public abstract class ResponseCommon {

    @XmlTransient
    private String errorMessage;

    public String getErrorMessage() {
        return errorMessage;
    }

    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }

    public abstract Object getValuableData();
}

GetBjxsDataResponse.java

import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "GetBjxsDataResponse", namespace = NamespaceMapper.WS_URI)
@XmlAccessorType(XmlAccessType.FIELD)
public class GetBjxsDataResponse extends ResponseCommon {

    @XmlAccessorType(XmlAccessType.FIELD)
    private static class GetBjxsDataResult {

        @XmlRootElement
        @XmlAccessorType(XmlAccessType.FIELD)
        private static class Diffgram {

            @XmlAccessorType(XmlAccessType.FIELD)
            private static class NewDataSet {

                @XmlElement(name = "Table")
                private List<Object> lists;
            }

            @XmlElement(name = "NewDataSet")
            private NewDataSet newDataSet;
        };

        @XmlElement
        private Object schema;

        @XmlElement
        private Diffgram diffgram;
    };

    @XmlElement(name="GetBjxsDataResult")
    private GetBjxsDataResult getBjxsDataResult;

    @Override
    public Object getValuableData() {
        return getBjxsDataResult.diffgram.newDataSet.lists;
    }
}

MainTest.java

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

public class MainTest {

    public static void main(String[] args) throws JAXBException {
        System.out.println("---");
        String str = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
                + "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n" 
                + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"> \n"
                + "<soap:Body> \n"
                    + "<GetBjxsDataResponse xmlns=\"http://tempuri.org/\"> \n"
                        + "<GetBjxsDataResult> \n"
                            + "<xs:schema id=\"NewDataSet\" xmlns=\"\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"     xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\"> \n"
                                + "<xs:element name=\"NewDataSet\" msdata:IsDataSet=\"true\" msdata:MainDataTable=\"Table\" msdata:UseCurrentLocale=\"true\"> \n"
                                    + "<xs:complexType> \n"
                                        + "<xs:choice minOccurs=\"0\" maxOccurs=\"unbounded\"> \n"
                                            + "<xs:element name=\"Table\"> \n"
                                                + "<xs:complexType> \n"
                                                    + "<xs:sequence> \n"
                                                        + "<xs:element name=\"xh\" type=\"xs:string\" minOccurs=\"0\" /> \n"
                                                        + "<xs:element name=\"bjbh\" type=\"xs:string\" minOccurs=\"0\" /> \n"
                                                        + "<xs:element name=\"bnbh\" type=\"xs:int\" minOccurs=\"0\" /> \n"
                                                        + "<xs:element name=\"xm\" type=\"xs:string\" minOccurs=\"0\" /> \n"
                                                        + "<xs:element name=\"bjmc\" type=\"xs:string\" minOccurs=\"0\" /> \n"
                                                    + "</xs:sequence> \n"
                                                + "</xs:complexType> \n"
                                            + "</xs:element> \n"
                                        + "</xs:choice> \n"
                                    + "</xs:complexType> \n"
                                + "</xs:element> \n"
                            + "</xs:schema> \n"
                            + "<diffgr:diffgram xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\" xmlns:diffgr=\"urn:schemas-microsoft-com:xml-diffgram-v1\"> \n"
                                + "<NewDataSet xmlns=\"\"> \n"
                                    + "<Table diffgr:id=\"Table1\" msdata:rowOrder=\"0\"> \n"
                                        + "<xh>320130001</xh> \n"
                                        + "<bjbh>3101</bjbh> \n"
                                        + "<bnbh>1</bnbh> \n"
                                        + "<xm>陈馨儿</xm> \n"
                                        + "<bjmc>高一(01)班          </bjmc> \n"
                                    + "</Table> \n"
                                    + "<Table diffgr:id=\"Table2\" msdata:rowOrder=\"1\"> \n"
                                        + "<xh>320130002</xh> \n"
                                        + "<bjbh>3101</bjbh> \n"
                                        + "<bnbh>2</bnbh> \n"
                                        + "<xm>丁灵</xm> \n"
                                        + "<bjmc>高一(01)班          </bjmc> \n"
                                    + "</Table> \n"
                                    + "<Table diffgr:id=\"Table3\" msdata:rowOrder=\"2\"> \n"
                                        + "<xh>320130003</xh> \n"
                                        + "<bjbh>3101</bjbh> \n"
                                        + "<bnbh>3</bnbh> \n"
                                        + "<xm>童欣欣</xm> \n"
                                        + "<bjmc>高一(01)班          </bjmc> \n"
                                    + "</Table> \n"
                                + "</NewDataSet> \n"
                            + "</diffgr:diffgram> \n"
                        + "</GetBjxsDataResult> \n"
                    + "</GetBjxsDataResponse> \n"
                + "</soap:Body> \n"
            + "</soap:Envelope> \n";
        System.out.println(str);

        JAXBContext jaxbContext2 =JAXBContext.newInstance(
            Envelope.class, GetBjxsDataResponse.class);

        InputStream is = new ByteArrayInputStream(str.getBytes());
        Unmarshaller unmarshaller = jaxbContext2.createUnmarshaller();
        Envelope responseEnvelope = (Envelope)unmarshaller.unmarshal(is);

        GetBjxsDataResponse getBjxsDataResponse = 
            (GetBjxsDataResponse)responseEnvelope.getBody().getMethod();

        @SuppressWarnings("unchecked")
        List<Object> bjxsDatas = (List<Object>)getBjxsDataResponse.getValuableData();
        System.out.println(bjxsDatas.size());
    }
}

回答1:


Finally I choose to parse the XML-format response by JAXM api and turn the result to Java object instance by Java reflection.



来源:https://stackoverflow.com/questions/36691368/jaxb-unmarshal-wont-work-with-jdk-1-6

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!