2010-08-25 5 views
3

J'ai deux ensembles de XSD, un qui génère des appels basés sur RPC, et un autre qui définit les méthodes spécifiques au produit. L'objet RpcType (généré par jaxb2) a une méthode « setRpcOperation » définie par:L'objet généré JAXB2 a été généré en JAXBElement?

RpcType.setRpcOperation(JAXBElement<? extends RpcOperationType>) 

Cet objet « de RpcOperation » doit être la « méthode spécifique du produit » décrit ci-dessus. Un exemple est (également produit par jaxb2):

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "get-user-stats", propOrder = { 
    "reset" 
}) 
public class GetUserStats { 

    protected Boolean reset; 

    /** 
    * Gets the value of the reset property. 
    * 
    * @return 
    *  possible object is 
    *  {@link Boolean } 
    *  
    */ 
    public Boolean isReset() { 
     return reset; 
    } 

    /** 
    * Sets the value of the reset property. 
    * 
    * @param value 
    *  allowed object is 
    *  {@link Boolean } 
    *  
    */ 
    public void setReset(Boolean value) { 
     this.reset = value; 
    } 

} 

Maintenant, est-il possible de créer une instance de « GetUserStatus » et l'ajouter à l'objet RpcType via setRpcOperation?

Répondre

3

Ce type de scénario est commun:

  • Un schéma pour représenter le message
  • Plusieurs schémas pour représenter la charge utile.

ci-dessous est une façon cela pourrait se faire:

message schéma - message.xsd

Avoir un schéma XML pour représenter l'enveloppe de votre message. Introduisez un type pour représenter le corps du message. Ce type sera étendu par les différentes charges utiles.

<?xml version="1.0" encoding="UTF-8"?> 
<xsd:schema 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://www.example.org/message" 
    xmlns="http://www.example.org/message" 
    elementFormDefault="qualified"> 

    <xsd:element name="message"> 
     <xsd:complexType> 
      <xsd:sequence> 
       <xsd:element name="body" type="body"/> 
      </xsd:sequence> 
     </xsd:complexType> 
    </xsd:element> 

    <xsd:complexType name="body"> 
    </xsd:complexType> 

</xsd:schema> 

Schéma Payload - customer.xsd

Ce schéma correspond à un type spécifique de la charge utile du message. Notez comment le type de client étend le type de corps à partir du schéma de message.

<?xml version="1.0" encoding="UTF-8"?> 
<xsd:schema 
    targetNamespace="http://www.example.org/customer" 
    xmlns="http://www.example.org/customer" 
    xmlns:m="http://www.example.org/message" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    elementFormDefault="qualified"> 

    <xsd:import schemaLocation="message.xsd" namespace="http://www.example.org/message"/> 

    <xsd:complexType name="customer"> 
     <xsd:complexContent> 
      <xsd:extension base="m:body"> 
       <xsd:sequence> 
        <xsd:element name="name" type="xsd:string"/> 
       </xsd:sequence> 
      </xsd:extension> 
     </xsd:complexContent> 
    </xsd:complexType> 

</xsd:schema> 

org.example.message.package-info

Cette classe a été générée à partir message.xsd.

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.example.org/message", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) 
package org.example.message; 

org.example.message.Message

Cette classe a été générée à partir message.xsd.

package org.example.message; 

import javax.xml.bind.annotation.*; 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "", propOrder = { 
    "body" 
}) 
@XmlRootElement(name = "message") 
public class Message { 

    @XmlElement(required = true) 
    protected Body body; 

    public Body getBody() { 
     return body; 
    } 

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

} 

org.example.message.Body

Cette classe a été générée à partir message.xsd.

package org.example.message; 

import javax.xml.bind.annotation.*; 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "body") 
public class Body { 

} 

org.example.customer.package-info

Cette classe a été générée à partir customer.xsd.

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.example.org/customer", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) 
package org.example.customer; 

org.example.customer.Client

Cette classe a été générée à partir customer.xsd.

package org.example.customer; 

import javax.xml.bind.annotation.*; 
import org.example.message.Body; 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "customer", propOrder = { 
    "name" 
}) 

public class Customer extends Body { 

    @XmlElement(required = true) 
    protected String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String value) { 
     this.name = value; 
    } 

} 

Classe de démonstration

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Marshaller; 

import org.example.customer.*; 
import org.example.message.*; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Message.class, Customer.class); 

     Message message = new Message(); 
     Customer customer = new Customer(); 
     customer.setName("Jane Doe"); 
     message.setBody(customer); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(message, System.out); 
    } 
} 

Sortie

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<message xmlns="http://www.example.org/message" xmlns:ns2="http://www.example.org/customer"> 
    <body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:customer"> 
     <ns2:name>Jane Doe</ns2:name> 
    </body> 
</message> 

EDIT # 1

En réponse à votre seco e question (Cast JAXB2 generated object to JAXBElement?)

Je ne vois pas où le JAXBElement entre en jeu avec cet exemple. Je suis en mesure d'exécuter le code suivant:

import generated.GetFailedLoginCount; 
import ietf.params.xml.ns.netconf.base._1.RpcType; 

public class Demo { 

    public static void main(String[] args) { 
     RpcType rpc = new RpcType(); 
     rpc.setMessageId("123"); 
     GetFailedLoginCount rpcOperation = new GetFailedLoginCount(); 
     rpc.setRpcOperation(rpcOperation); 
    } 
} 

EDIT # 2

Après avoir modifié l'importation d'importer à http://www.iana.org/assignments/xml-registry/schema/netconf.xsd je vois le même comportement que vous.

Pour définir la propriété correctement, vous devez faire quelque chose comme:

RpcType rpc = new RpcType(); 
GetFailedLoginCount rpcOperation = new GetFailedLoginCount(); 
rpcOperation.setReset(true); 
JAXBElement<GetFailedLoginCount> rpcOperationJE = new JAXBElement(new QName("foo"), GetFailedLoginCount.class, rpcOperation); 
rpc.setRpcOperation(rpcOperationJE); 

JAXBElement fournit le nom de l'élément de la valeur GetFailedLoginCount. Cela est nécessaire parce que l'élément correspondant à la propriété rpcOperation est substituable:

<xs:element name="get-config" type="getConfigType" substitutionGroup="rpcOperation" /> 

Dans votre schéma que les importations vous netconf.xsd devriez avoir un élément de type « get-comte-login failed » qui peut être remplacé par "rpcOperation". Ceci sera fourni en tant que QName au JAXBElement. Étant donné que nous avons utilisé le nom de l'élément « foo » au-dessus de la mise à jour du schéma ressemblerait à ceci:

<xs:element name="foo" type="get-failed-login-count" substitutionGroup="rpcOperation" /> 
+0

est-il un moyen de faire # 1 dans le xsd? et pour # 2, il semble que vous ayez les trois options identiques – wuntee

+0

J'ai mis à jour ma réponse pour inclure un exemple. –

+0

J'ai aussi posté un exemple sur mon blog où l'objet de message a une propriété de type objet, et tire parti de l'annotation @XmlAnyElement pour trier la charge utile: http://bdoughan.blogspot.com/2010/08/using-xmlanyelement -to-build-generic.html –

0

Ok, alors voici un sous-ensemble de ce que je suis en train de faire. L'exemple ci-dessus a été extrêmement utile, mais je ne suis toujours pas en mesure de créer un JAXBElement:

enveloppe de base se trouve: http://www.iana.org/assignments/xml-registry/schema/netconf.xsd

Payload rpcOperationType (j'ai ajouté les ** lignes):

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:dmi="http://xml.juniper.net/dmi" 
** xmlns:netconf="urn:ietf:params:xml:ns:netconf:base:1.0" 
> 
**<xs:import schemaLocation="netconf.xsd" namespace="urn:ietf:params:xml:ns:netconf:base:1.0"/> 
<!-- get-failed-login-count --> 
<xs:complexType name="get-failed-login-count"> 
**<xs:complexContent> 
** <xs:extension base="netconf:rpcOperationType"> 
    <xs:annotation> 
    <xs:appinfo> 
     <dmi:rpc-info> 
     <name>Get failed login count for Authentication failure and Exceeded user</name> 
     <description> 
      This command returns the Number of Logins refused due to exceeding allowed limits and Auth failure (24 hour moving window) 
     </description> 
     <rpc-reply-tag>failed-login-count</rpc-reply-tag> 
     </dmi:rpc-info> 
    </xs:appinfo> 
    </xs:annotation> 
    <xs:sequence> 
    <xs:element name="reset" type="xs:boolean" minOccurs="0"> 
     <xs:annotation> 
     <xs:appinfo> 
      <dmi:param-info> 
      <name>Reset Stats</name> 
      <description> 
       This will govern the reseting of this statistics data. By default, the data is not reset. 
      </description> 
      </dmi:param-info> 
     </xs:appinfo> 
     </xs:annotation> 
    </xs:element> 
    </xs:sequence> 
** </xs:extension> 
**</xs:complexContent> 
</xs:complexType> 

maintenant, la classe GetFailedLogin générée étend RpcOperationType, mais je ne suis pas sûr de savoir comment il défini dans l'objet RpcType:

RpcType rpc = new RpcType(); 
    rpc.setMessageId("123"); 
    GetFailedLoginCount rpcOperation = new GetFailedLoginCount(); 
    rpc.setRpcOperation(); // Expects JAXBElement<? Extends RpcOperationType> 
+0

Est-ce une question ou une réponse? – skaffman

+0

Question ... la dernière ligne 'rpc.setRpcOperation();' a besoin de quelque chose qui lui soit passé ... Est-il possible que l'objet rpcOperation tape JAXBElement ? – wuntee

Questions connexes