问题
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