我是JAXB的新手。我想要做的就是,给定一个现有的xml字符串封送它,然后在ejb中返回它。问题是以下代码似乎只适用于根节点,而不是子节点。我希望它适用于整个事情。如果有任何帮助,我没有改变通过提供方案生成的任何代码。任何指针都会有所帮助,谢谢。
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Stateless;
import javax.jws.WebService;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import org.netbeans.j2ee.wsdl.test.newwsdl.NewWSDLPortType;
import org.netbeans.xml.schema.newxmlschema.*;
@WebService(serviceName = "newWSDLService", portName = "newWSDLPort", endpointInterface = "org.netbeans.j2ee.wsdl.test.newwsdl.NewWSDLPortType", targetNamespace = "http://j2ee.netbeans.org/wsdl/test/newWSDL", wsdlLocation = "META-INF/wsdl/NewWebServiceFromWSDL/newWSDLWrapper.wsdl")
@Stateless
public class NewWebServiceFromWSDL implements NewWSDLPortType {
public Root newWSDLOperation() {
String xml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+"<ns0:root xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'"
+" xmlns:ns0='http://xml.netbeans.org/schema/newXmlSchema'"
+" xsi:schemaLocation='http://xml.netbeans.org/schema/newXmlSchema newXmlSchema.xsd'>"
+" <ns0:node>"
+" <ns0:name>asdf</ns0:name>"
+" <ns0:value>asdf</ns0:value>"
+" <ns0:date>2009-01-01</ns0:date>"
+" </ns0:node>"
+" <ns0:node>"
+" <ns0:name>asdf</ns0:name>"
+" <ns0:value>asdf</ns0:value>"
+" <ns0:date>2009-01-01</ns0:date>"
+" </ns0:node>"
+" <ns0:node>"
+" <ns0:name>asdf</ns0:name>"
+" <ns0:value>asdf</ns0:value>"
+" <ns0:date>2009-01-01</ns0:date>"
+" </ns0:node>"
+"</ns0:root>";
Root root = null;
try {
root = jaxbUnmarshalFromString(xml);
} catch (Throwable ex) {
Logger.getLogger(NewWebServiceFromWSDL.class.getName()).log(Level.SEVERE, null, ex);
}
return root;
}
private Root jaxbUnmarshalFromString(String str) throws javax.xml.bind.JAXBException {
Root ret = null;
javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance(Root.class.getPackage().getName());
javax.xml.bind.Unmarshaller unmarshaller = jaxbCtx.createUnmarshaller();
ret = (Root) ((JAXBElement)unmarshaller.unmarshal(new java.io.StringReader(str))).getValue();
return ret;
}
}
这是方案:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://xml.netbeans.org/schema/newXmlSchema"
xmlns:tns="http://xml.netbeans.org/schema/newXmlSchema"
elementFormDefault="qualified">
<xsd:complexType name="root">
<xsd:sequence>
<xsd:element name="node" type="tns:node" maxOccurs="unbounded" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="node">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="value" type="xsd:string"/>
<xsd:element name="date" type="xsd:date"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="root" type="tns:root"/>
</xsd:schema>
从方案生成的类:
package org.netbeans.xml.schema.newxmlschema;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;
@XmlRegistry
public class ObjectFactory {
private final static QName _Root_QNAME = new QName("http://xml.netbeans.org/schema/newXmlSchema", "root");
/**
* Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: org.netbeans.xml.schema.newxmlschema
*
*/
public ObjectFactory() {
}
/**
* Create an instance of {@link Root }
*
*/
public Root createRoot() {
return new Root();
}
/**
* Create an instance of {@link Node }
*
*/
public Node createNode() {
return new Node();
}
/**
* Create an instance of {@link JAXBElement }{@code <}{@link Root }{@code >}}
*
*/
@XmlElementDecl(namespace = "http://xml.netbeans.org/schema/newXmlSchema", name = "root")
public JAXBElement<Root> createRoot(Root value) {
return new JAXBElement<Root>(_Root_QNAME, Root.class, null, value);
}
}
package org.netbeans.xml.schema.newxmlschema;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for root complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="root">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="node" type="{http://xml.netbeans.org/schema/newXmlSchema}node" maxOccurs="unbounded" minOccurs="0"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "root", propOrder = {
"node"
})
public class Root {
protected List<Node> node;
/**
* Gets the value of the node property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the node property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getNode().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {@link Node }
*
*
*/
public List<Node> getNode() {
if (node == null) {
node = new ArrayList<Node>();
}
return this.node;
}
}
package org.netbeans.xml.schema.newxmlschema;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.datatype.XMLGregorianCalendar;
/**
* <p>Java class for node complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="node">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="name" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="value" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="date" type="{http://www.w3.org/2001/XMLSchema}date"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "node", propOrder = {
"name",
"value",
"date"
})
public class Node {
@XmlElement(required = true)
protected String name;
@XmlElement(required = true)
protected String value;
@XmlElement(required = true)
@XmlSchemaType(name = "date")
protected XMLGregorianCalendar date;
/**
* Gets the value of the name property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getName() {
return name;
}
/**
* Sets the value of the name property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setName(String value) {
this.name = value;
}
/**
* Gets the value of the value property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getValue() {
return value;
}
/**
* Sets the value of the value property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setValue(String value) {
this.value = value;
}
/**
* Gets the value of the date property.
*
* @return
* possible object is
* {@link XMLGregorianCalendar }
*
*/
public XMLGregorianCalendar getDate() {
return date;
}
/**
* Sets the value of the date property.
*
* @param value
* allowed object is
* {@link XMLGregorianCalendar }
*
*/
public void setDate(XMLGregorianCalendar value) {
this.date = value;
}
}
和WSDL:
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="newWSDL" targetNamespace="http://j2ee.netbeans.org/wsdl/test/newWSDL"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://j2ee.netbeans.org/wsdl/test/newWSDL" xmlns:ns="http://xml.netbeans.org/schema/newXmlSchema" xmlns:plnk="http://docs.oasis-open.org/wsbpel/2.0/plnktype">
<types>
<xsd:schema targetNamespace="http://j2ee.netbeans.org/wsdl/test/newWSDL">
<xsd:import namespace="http://xml.netbeans.org/schema/newXmlSchema" schemaLocation="newXmlSchema.xsd"/>
</xsd:schema>
</types>
<message name="newWSDLOperationRequest"/>
<message name="newWSDLOperationResponse">
<part name="part1" type="ns:root"/>
</message>
<portType name="newWSDLPortType">
<operation name="newWSDLOperation">
<input name="input1" message="tns:newWSDLOperationRequest"/>
<output name="output1" message="tns:newWSDLOperationResponse"/>
</operation>
</portType>
<plnk:partnerLinkType name="newWSDL">
<plnk:role name="newWSDLPortTypeRole" portType="tns:newWSDLPortType"/>
</plnk:partnerLinkType>
</definitions>
以下肥皂电话:
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header/>
<S:Body>
<ns2:newWSDLOperation xmlns:ns2="http://j2ee.netbeans.org/wsdl/test/newWSDL" xmlns:ns3="http://xml.netbeans.org/schema/newXmlSchema"/>
</S:Body>
</S:Envelope>
返回:
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns3:newWSDLOperationResponse xmlns:ns2="http://xml.netbeans.org/schema/newXmlSchema" xmlns:ns3="http://j2ee.netbeans.org/wsdl/test/newWSDL">
<part1/>
</ns3:newWSDLOperationResponse>
</S:Body>
</S:Envelope>
答案 0 :(得分:0)
您在编组后吞下例外。
try {
root = jaxbUnmarshalFromString(xml);
} catch (Throwable ex) {
// !!! Exception caught here and not rethrown
Logger.getLogger(NewWebServiceFromWSDL.class.getName()).log(Level.SEVERE, null, ex);
}
return root; // !!!root is null here
我的猜测是,当你返回root时,root为null。记录您的异常时检查日志。
答案 1 :(得分:0)
我刚刚遇到一个问题,JAXB unmarshaller返回一个空的根音符。事实证明,在使用PowerMockito运行JUnit测试时,我只获得空的根节点。我想知道幕后发生的事情是否阻止了“真正的”unmarshaller的运行。