La mia domanda è molto simile a How to prevent marshalling empty tags in JAXB when string is empty but not nullJAXB maresciallo stringa vuota a livello globale Null
La differenza è che io sono in grado di aggiungere l'annotazione a package-info.java come tutti i nostri tipi JAXB sono generate da schemi di ogni costruzione . Inoltre preferirei non cambiare i provider JAXB se possibile.
Quello che voglio ottenere è che l'impostazione di una stringa vuota non creerà l'elemento, ma ho bisogno di impostare questo per tutti i tipi JAXB generati da molti schemi. C'è un modo per applicarlo a tutti i campi String in tutte le classi JAXB generate?
Aggiornamento Sono riuscito a ottenere la generazione di adattatore di XML per tutte le stringhe nello schema apportando le seguenti modifiche:
Nel POM del progetto, ho aggiunto questo al Maven-jaxb2-plugin:
<bindingDirectory>src/main/resources</bindingDirectory>
<bindingIncludes>
<include>bindings.xjb</include>
</bindingIncludes>
e qui è il mio file bindings.xjb:
<jxb:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb" version="2.1">
<jxb:globalBindings>
<jxb:javaType name="java.lang.String" xmlType="xs:token"
parseMethod="com.project.Formatter.parseString"
printMethod="com.project.Formatter.printString"/>
</jxb:globalBindings>
</jxb:bindings>
E la formattazione metodo:
public static String printString(final String value)
{
if (StringUtils.isBlank(value))
{
return null;
}
return value;
}
Il problema è che questo causa un'eccezione Pointer nullo in profondità all'interno di JAXB. Ecco StackTrace:
Caused by: java.lang.NullPointerException
at com.sun.xml.bind.v2.runtime.output.SAXOutput.text(SAXOutput.java:158)
at com.sun.xml.bind.v2.runtime.XMLSerializer.leafElement(XMLSerializer.java:321)
at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$1.writeLeafElement(RuntimeBuiltinLeafInfoImpl.java:210)
at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$1.writeLeafElement(RuntimeBuiltinLeafInfoImpl.java:209)
at com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor$CompositeTransducedAccessorImpl.writeLeafElement(TransducedAccessor.java:250)
at com.sun.xml.bind.v2.runtime.property.SingleElementLeafProperty.serializeBody(SingleElementLeafProperty.java:98)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:322)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:681)
at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:150)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:322)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:681)
at com.sun.xml.bind.v2.runtime.property.ArrayElementNodeProperty.serializeItem(ArrayElementNodeProperty.java:65)
at com.sun.xml.bind.v2.runtime.property.ArrayElementProperty.serializeListBody(ArrayElementProperty.java:168)
at com.sun.xml.bind.v2.runtime.property.ArrayERProperty.serializeBody(ArrayERProperty.java:152)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:322)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:681)
at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:150)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:322)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:681)
at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:150)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:322)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:681)
at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:150)
at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:156)
at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:185)
at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeBody(ElementBeanInfoImpl.java:305)
at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot(ElementBeanInfoImpl.java:312)
at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot(ElementBeanInfoImpl.java:71)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:490)
at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:328)
at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:257)
at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:103)
La causa di questo problema si riduce a questo metodo:
com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor.CompositeTransducedAccessorImpl.hasValue(BeanT)
Il metodo sopra renderà dell'elemento se il valore non è nullo prima alcun adattatore viene eseguito .
C'è un modo per ignorare la funzione di accesso utilizzato in JAXB in modo che questo verrà eseguito l'adattatore prima di determinare se eseguire il rendering l'elemento? C'è un altro modo per ottenere ciò che voglio?
Date un'occhiata http://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/1.5/tutorial/doc JAXB Binding /JAXBUsing4.html – anazimok
Sì, ho dato un'occhiata a questo. Sfortunatamente i documenti dello schema sono piuttosto complessi e ci sono circa 30 schemi diversi su cui avrei bisogno di applicarlo. Per quanto ne so, è necessario definire un singolo schema per ogni associazione. C'è un modo per applicare l'associazione a tutte le classi JAXB generate? –
Puoi definire globalBinding vedere il link che ho postato, non riesco a ricordare quale attributo esattamente ma uno di loro aggiunge nillable a ciascun elemento. Forse questo aiuterà: http://stackoverflow.com/questions/4413281/how-do-i-prevent-jaxbelementstring-from-being-generated-in-a-cxf-web-service-c – anazimok