2011-09-07 2 views
3

J'utilise le org.jvnet.jaxb2.maven2:maven-jaxb2-plugin pour créer des POJO à partir de fichiers de schéma XSD.Insérer un setter personnalisé dans maven-jaxb2-plugin

Maintenant, je veux insérer quelque chose comme un setter personnalisé. Il devrait couper toutes les chaînes et devrait supprimer certains caractères.

Savez-vous comment faire?


Le fichier XJB:

<?xml version="1.0" encoding="UTF-8"?> 
<jaxb:bindings version="2.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"> 
    <jaxb:bindings schemaLocation="my-schema-xml4.xsd" node="/xs:schema"> 
     <xjc:javaType name="java.lang.String" adapter="my.StringAdapter" /> 
    </jaxb:bindings> 
</jaxb:bindings> 

Solution pour les types Java de liaison:

<?xml version="1.0" encoding="UTF-8" ?> 
<bindings version="2.0" xmlns="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"> 
    <bindings schemaLocation="mySchema-xml4.xsd" node="/xs:schema"> 
     <globalBindings> 
      <xjc:javaType name="java.lang.String" xmlType="xs:string" 
       adapter="com.name.MyAdapter" /> 
        <xjc:javaType name="java.lang.String" xmlType="xs:anySimpleType" 
       adapter="com.name.MyAdapter" /> 
     </globalBindings> 
    </bindings> 
</bindings> 

Mais le @XmlJavaTypeAdapter n'est toujours pas ajouté à la propriété content dans les nœuds avec un contenu mixte, bien que la propriété ait le type java.lang.String.

Répondre

1

Je pense que la meilleure façon d'y parvenir est d'implémenter un propre XmlAdapter et de le configurer via la personnalisation de la propriété. Vous pouvez le faire avec une personnalisation standard jaxb:property ou avec le annotate plugin.

jaxb:property:

<jaxb:property> 
    <jaxb:baseType> 
     <xjc:javaType name="java.lang.String" 
     adapter="com.acme.foo.MyAdapter"/> 
    </jaxb:baseType> 
    </jaxb:property> 

plugin Annoter:

<annox:annotate target="field"> 
    <annox:annotate 
     annox:class="javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter" 
     value="com.acme.foo.MyAdapter"/> 
    </annox:annotate> 

Voir l'exemple de projet ici:

https://svn.java.net/svn/jaxb2-commons~svn/basics/trunk/tests/one/

+0

J'ai implémenté le XmlAdapter, mais je ne sais pas comment l'ajouter. S'il vous plaît voir mon fichier XJB dans la question éditée. –

+1

S'il vous plaît relire ma réponse, 'jaxb: property' est la voie à suivre. Il y a aussi un lien vers un exemple de projet - l'avez-vous vérifié? – lexicore

+0

J'ai relu votre réponse et j'ai également vérifié l'exemple de projet, mais je ne sais pas où ajouter le 'jaxb: property' quand je veux qu'il affecte toutes les chaînes dans le schéma. –

0

Si votre XSD ne changera pas à l'avenir juste générer le POJO, commentez le plugin JAXB et modifiez la source à la main.

Si votre XSD change rarement, vous pouvez toujours utiliser cette solution avec un système de contrôle de version. Validez la source générée, modifiez les POJO et validez les modifications. La prochaine fois que le XSD est modifié, générez un patch entre les deux validations, générez les POJO à partir du nouveau XSD et appliquez le patch. J'ai trouvé cette solution beaucoup plus simple dans les cas où le XSD ne change presque jamais.

+0

Malheureusement, j'obtiens l'exception 'javax.xml.stream.FactoryConfigurationError: Provider com.bea.xml.stream.MXParserFactory non trouvé' quand je veux créer un' XMLInputFactory'. –

0

Une autre approche consisterait à utiliser un StAX StreamReaderDelegate pour manipuler le texte XML avant sa réception par l'implémentation JAXB.

Démo

Votre code ressemblerait à quelque chose comme ce qui suit. Vous mettre en œuvre un StreamReaderDelegate pour manipuler le texte renvoyé des événements texte:

package forum7329881; 

import java.io.FileInputStream; 
import javax.xml.bind.*; 
import javax.xml.stream.*; 
import javax.xml.stream.util.StreamReaderDelegate; 

public class Demo { 

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

     XMLInputFactory xif = XMLInputFactory.newInstance(); 
     XMLStreamReader xsr = xif.createXMLStreamReader(new FileInputStream("src/forum7329881/input.xml")); 
     xsr = new MyStreamReaderDelegate(xsr); 

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     Customer customer = (Customer) unmarshaller.unmarshal(xsr); 

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

    private static class MyStreamReaderDelegate extends StreamReaderDelegate { 

     public MyStreamReaderDelegate(XMLStreamReader xsr) { 
      super(xsr); 
     } 


     @Override 
     public String getText() { 
      return super.getText().trim(); 
     } 

     @Override 
     public char[] getTextCharacters() { 
      return getText().toCharArray(); 
     } 

     @Override 
     public int getTextLength() { 
      return getText().length(); 
     } 

     @Override 
     public int getTextStart() { 
      return 0; 
     } 

    } 

} 

entrée .xml

est entrée exemple ci-dessous qui contient des espaces dans les nœuds de texte:

<customer Id="1"> 
    <name> Jane Doe </name> 
    <address> 
     <street> 123 A Street </street> 
    </address> 
</customer> 

Sortie

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<customer> 
    <address> 
     <street>123 A Street A</street> 
    </address> 
    <name>Jane Doe</name> 
</customer> 

client

package forum7329881; 

import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Customer { 

    private String name; 
    private Address address; 

    public String getName() { 
     return name; 
    } 

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

    public Address getAddress() { 
     return address; 
    } 

    public void setAddress(Address address) { 
     this.address = address; 
    } 

} 

Adresse

package forum7329881; 

public class Address { 

    private String street; 

    public String getStreet() { 
     return street; 
    } 

    public void setStreet(String street) { 
     this.street = street; 
    } 

} 

Pour plus d'informations

est Ci-dessous un lien vers un exemple plus détaillé où je un StAX StreamReaderDelegate pour soutenir le cas unmarshalling insensible:

0

À mon avis, vous devriez utiliser AOP, Pick Spring AOP, par exemple, Intercept les méthodes de l'adaptateur pour avoir la logique de garniture/bande. En fait, cela peut maintenant être une logique générique qui s'appliquerait à tous les types de chaînes. Si cela semble convaincant, je peux en outre aider avec le code

+0

Je voudrais juste savoir où insérer l'intercepteur. –

Questions connexes