2009-09-25 5 views
0

Je suis nouveau à JAXB. Tout ce que je veux faire est, donné une chaîne de xml existante marshal, et le renvoyer dans un ejb. Le problème est que le code suivant ne semble fonctionner que pour le nœud racine, et non pour les enfants. Je voudrais que ça marche pour tout ça. Si c'est de l'aide, je n'ai pas modifié le code généré par l'alimentation dans le schéma. Tout pointeur serait utile, merci.JAXB seulement poste racine de marshals/unmarshals

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; 
    } 

} 

Voici le schéma:

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

classes générées du système:

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> 
* &lt;complexType name="root"> 
* &lt;complexContent> 
*  &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> 
*  &lt;sequence> 
*   &lt;element name="node" type="{http://xml.netbeans.org/schema/newXmlSchema}node" maxOccurs="unbounded" minOccurs="0"/> 
*  &lt;/sequence> 
*  &lt;/restriction> 
* &lt;/complexContent> 
* &lt;/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> 
* &lt;complexType name="node"> 
* &lt;complexContent> 
*  &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> 
*  &lt;sequence> 
*   &lt;element name="name" type="{http://www.w3.org/2001/XMLSchema}string"/> 
*   &lt;element name="value" type="{http://www.w3.org/2001/XMLSchema}string"/> 
*   &lt;element name="date" type="{http://www.w3.org/2001/XMLSchema}date"/> 
*  &lt;/sequence> 
*  &lt;/restriction> 
* &lt;/complexContent> 
* &lt;/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; 
    } 

} 

Et 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> 

Le soa suivant appel p:

<?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> 

Retours:

<?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

il semble que cela ne fonctionne pas non plus sur root. il retourne juste un nom de message vide "part1" –

+0

vous avalez l'exception après marshalling. ma conjecture est que la racine est nulle quand yo le renvoie. Vérifiez vos journaux. –

Répondre

0

vous avalez l'exception après triage.

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 

Ma conjecture est que la racine est nulle quand vous la renvoyez. Vérifiez vos journaux car votre exception est enregistrée.

+0

Rien dans les journaux. Je l'ai parcouru dans le débogueur, et aucune exception n'a été levée. root n'est pas nul au retour, mais son objet node est. –

+0

Hmm, ok. Étrange. Pouvez-vous poster vos cours générés? –

0

J'ai juste eu un problème avec le retour unmarshaller JAXB une note de racine vide. Il s'avère que je n'ai que le nœud racine vide lors de l'exécution de tests JUnit avec PowerMockito. Je me demande s'il se passe quelque chose derrière les scènes qui empêche le «vrai» démon de fonctionner.