2009-05-13 29 views
46

Esta es una solicitud bastante simple, pero simplemente no encontré la manera de hacerlo.JAXB Marshalling con campos nulos

Básicamente estoy tratando de configurar un rol en JAXB que diga que siempre que se encuentre un campo nulo, en lugar de ignorarlo en la salida, configúrelo en un valor vacío. Así que para la clase:

@XMLRootElement 
Class Foo { 
    Integer num; 
    Date date; 
…. 
} 

Cuando esto ha sido movilizados en el archivo XML si el campo de fecha es nulo, mi salida no tiene ese elemento en ella. Lo que quiero hacer es incluir todos los campos en la salida; y si son nulas, reemplácelas con, digamos, un espacio en blanco. Así que la salida debe ser:

<foo> 
    <num>123</num> 
    <date></date> 
</foo> 

Gracias,

Jalpesh.

+1

¡Una gran pregunta y respuesta! Me encontré con el mismo problema, y ​​fue una gran ayuda. –

Respuesta

4

Pero pero ... una cadena vacía no es una representación léxica válida para una fecha, por lo que no puede hacer eso. es decir, si generó un documento XML con un valor vacío para un campo de fecha, no se validará correctamente.

En otras palabras, si el elemento tiene un dateminOccurs de 1 o más y no nillable, entonces es absolutamente necesario tener (1) o más fechas, que no puede ser nulo (o espacios en blanco, u otros no los valores)

+0

Solía ​​tener el primer párrafo de esta respuesta como un comentario (¡gracias a la encantadora persona que lo votó por votación!), Pero pensé que sería más útil como respuesta, ahora que me he expandido un poco. :-) –

+1

De acuerdo, pero no estoy validando el xml, y no tiene un esquema. Tener todos los campos presentes facilitará que el consumidor final descubra qué significa este xml. Antes de comenzar a criticarme por no tener un esquema xml :) Estoy usando esto desde otro framework (Jersey) que consume mis objetos de datos y escupe XML/Json usando JAXB. Entonces, el único control que tengo es sobre mis objetos de datos. Además, puedo ver un motivo para admitir valores nulos. Piensa en un caso de uso en el que quiero generar un archivo CSV de mi objeto de datos. Podría usar marshal.marshal (elem, myContentHandler). – Jalpesh

+0

contentHandler generaría un archivo CSV con el formato correcto, lo que solo se puede hacer si ninguno de mis campos de datos se ignora. – Jalpesh

1

Como se indica en la otra respuesta no es válida, ya que no es una fecha válida. Tenía un problema similar en el que quería tratar (lo mismo que) especialmente. Como no puede usar null, puede usar el mecanismo de valor predeterminado en JAXB. Lo siguiente establecerá el valor predeterminado si no se especifica ninguno. Puede a través del código detectar esta fecha especial y manejar este caso de excepción.

@XmlElement(defaultValue="1970-01-01T00:00:00.0-00:00") 

Por lo tanto, es posible detectar y vaciar el valor de la fecha, pero simplemente no puede usar el nulo para hacerlo.

38

Gracias chicos por sus respuestas.

Chris Dail - Intenté su enfoque, y realmente no hice lo que quería. JAXB seguía ignorando mis valores nulos, a pesar de definir un valor predeterminado para mis campos.

Me tropecé con la respuesta después de que alguien en los foros de Jersey me indicara la sección de documentación 2.2.12.8 No Value.

Básicamente, todo lo que tenía que hacer era añadir lo siguiente a mis campos:

@XmlElement(nillable = true) 

Una vez añadí que, JAXB se presentaba esos campos cuando marshalling ellos a XML como esto:

... 
<num>5</num> 
<date xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/> 
.... 
+0

Gran pregunta y respuesta: he publicado una pregunta de seguimiento sobre cómo simplificar la sintaxis nula: http://stackoverflow.com/questions/8198945/how-to-set-non-namespaced-nil-and- datatype-attributes-in-jaxb –

1

En MOXy puede especificar cómo el jsonProvider debe hacer su trabajo para JAXB.

Así que cuando se hace JAX-RS, añadir siguiente código en su clase derivada de Aplicación

He utilizado este código en Tomcat 7 con buenos resultados. (eclipselink 2.4.1)

@ApplicationPath("/rest") 
public class RestApplication extends Application 
{ 

    ... 

public Set< Object> getSingletons() 
    { 

    HashSet<Object> set = new HashSet<Object>(1); 
    set.add(newMoxyJsonProvider()); 

    return set; 
    } 


public static MOXyJsonProvider newMoxyJsonProvider() 
    { 

    MOXyJsonProvider result = new MOXyJsonProvider(); 

    //result.setAttributePrefix("@"); 
    result.setFormattedOutput(false); 
    result.setIncludeRoot(false); 
    result.setMarshalEmptyCollections(true); 
    //result.setValueWrapper("$"); 

    return result; 
    } 

On Glassfish 3.1.2 y WAS 8.5 sin embargo, newMoxyJsonProvider() no es necesario, pero luego el servidor configura al proveedor JAXB. En el caso de Glassfish, que viene con MOXy, presencié los mismos problemas con los valores nulos. No se ha comprobado todavía, pero supongo que la respuesta está en configurar JAXB en el nivel del servidor de aplicaciones si es posible.

Cuestiones relacionadas