JAXB Маршаллинг с нулевыми полями

Это довольно простой запрос, но я просто не нашел способа сделать это.

Я в основном пытаюсь установить роль в JAXB, которая говорит, что всякий раз, когда встречается пустое поле, вместо игнорирования его в выходных данных, установите его в пустое значение. Итак, для класса:

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

Когда это было перенесено в файл XML, если поле даты пустое, мой вывод не содержит этого элемента. Что я хочу сделать, это включить все поля в вывод; и если они нулевые, замените их на - скажем, пустым Таким образом, вывод должен быть:

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

Спасибо,

Jalpesh.

5 ответов

Спасибо, ребята, за ваши ответы.

Крис Дэйл - я попробовал твой подход, но он не сделал то, что я хотел. JAXB все еще игнорировал мои нулевые значения, несмотря на определение значения по умолчанию для моих полей.

Я наткнулся на ответ после того, как кто-то на форумах Джерси указал мне на раздел документации 2.2.12.8.

По сути, все, что мне нужно было сделать, это добавить следующее в мои поля:

@XmlElement(nillable = true) 

Как только я добавлю это, JAXB отобразит эти поля при сортировке их в XML следующим образом:

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

Но, но... пустая строка не является допустимым лексическим представлением для даты, поэтому вы не можете этого сделать. то есть, если вы сгенерировали XML-документ с пустым значением для поля даты, он не будет проверен надлежащим образом.

Другими словами, если ваш date элемент имеет minOccurs из 1 или более и не nillable, тогда у вас обязательно должны быть (1 или более) даты, которые не могут быть нулевыми (или пробелами, или другими ненулевыми значениями).

Как указано в другом ответе является недействительным, так как это не является действительной датой. У меня была похожая проблема, в которой я специально хотел (так же, как) решить. Поскольку вы не можете использовать нуль, вы можете использовать механизм значений по умолчанию в JAXB. Следующее будет значение по умолчанию, если ничего не указано. Вы можете с помощью кода обнаружить эту особую дату и обработать это исключение.

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

Таким образом, можно обнаружить и очистить значение даты, но вы просто не можете использовать ноль для этого.

В MOXy вы можете указать, как jsonProvider должен выполнять свою работу для JAXB.

Поэтому, когда вы делаете JAX-RS, добавьте следующий код в ваш класс, полученный из Application

Я использовал этот код на Tomcat 7 с хорошими результатами. (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;
  }

Однако в Glassfish 3.1.2 и WAS 8.5 newMoxyJsonProvider() не требуется, но сервер JAXB настраивается сервером. В случае Glassfish, который поставляется с MOXy, я был свидетелем тех же проблем с нулевыми значениями. Пока не проверял, но думаю, что ответ заключается в настройке JAXB на уровне сервера приложений, если это вообще возможно.

Попробуй это:

marshal.setListener(new MarshallerListener());

с

public class MarshallerListener extends Marshaller.Listener {

    public static final String BLANK_CHAR = "";

    @Override
    public void beforeMarshal(Object source) {
        super.beforeMarshal(source);
        Field[] fields = source.getClass().getDeclaredFields();
        for (Field f : fields) {
            f.setAccessible(true);
            try {
                if (f.getType() == String.class && f.get(source) == null) {
                    f.set(source, BLANK_CHAR);
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
}
Другие вопросы по тегам