JAXB Marshalling with null fields

This is a pretty simple request, but I just didn't find a way to do it.

I'm basically trying to set up a role in JAXB which says that whenever an null field is encountered, instead of ignoring it in the output, set it to an empty value. So for the class :

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

When this has been marshalled into the XML file if the date field is null, my output does not have that element in it. What I want to do is include all the fields in the output; and if they are null, replace them with - say a blank. So the output should be :

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

Thanks,

Jalpesh.


Solution 1:

Thanks guys for your answers.

Chris Dail - I tried your approach, and it didn't really do what I wanted. JAXB was still ignoring my null values, in spite of defining a default value for my fields.

I did stumble across the answer after somebody in the Jersey forums pointed me to documentation section 2.2.12.8 No Value.

Basically, all I had to do was to add the following to my fields :

@XmlElement(nillable = true) 

Once I added that, JAXB would show up those fields when marshalling them to XML like this:

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

Solution 2:

But but but...a empty string is not a valid lexical representation for a date, so you can't do that. i.e., if you generated an XML document with an empty value for a date field, it won't validate properly.

In other words, if your date element has a minOccurs of 1 or more and not nillable, then you absolutely must have (1 or more) dates, which can't be null (or blanks, or other non-values).

Solution 3:

As indicated in the other answer is invalid since it is not a valid date. I had a similar issue where I wanted to handle (same as ) specially. Since you cannot use null, you can use the default value mechanism in JAXB. The following will default the value if none is specified. You can through code detect this special date and handle this exception case.

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

So it is possible to detected and empty date value but you just cannot use null to do it.

Solution 4:

In MOXy u can specify how the jsonProvider must do its job for JAXB.

So when doing JAX-RS, add following code in your class derived from Application

I used this code on Tomcat 7 with good results. (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 and WAS 8.5 however, newMoxyJsonProvider() is not needed, but then the JAXB provider gets configured by the server. In the case of Glassfish, which comes with MOXy, i witnessed same problems with null values. Did not check yet, but guess the answer is in configuring JAXB at application server level if possible at all.