JAXB: Как настроить сериализацию Xml двойных полей - PullRequest
7 голосов
/ 10 ноября 2010

У меня есть унаследованный класс с множеством открытых двойных полей.Все двойные поля инициализируются с Double.MAX_VALUE, чтобы указать, что они пусты.(Унаследованная сериализация закодирована, чтобы игнорировать поле и не сериализовать, если поле равно Double.MAX_VALUE).

Сейчас мы пытаемся сериализовать этот класс в Xml, используя JAXB Marshaller.Он работает нормально, за исключением того, что мы хотим предотвратить генерацию Xml для полей, равных Double.MAX_VALUE.

Мы не используем отдельную схему JAXB, просто помечаем наши классы различными javax.xml.bind.annotation аннотациями.Если используется схема, вы можете добавить элемент <javaType>, чтобы указать пользовательский преобразователь DataType.Есть ли способ сделать это, используя аннотации или программно?

После попытки подхода, рекомендованного ниже, я все еще не могу получить XmlAdapter подобранный:

@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(value=EmptyDoubleValueHandler.class, type=Double.class), @XmlJavaTypeAdapter(value=EmptyDoubleValueHandler.class, type=double.class)})
package tta.penstock.data.iserver;

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;

Мой класс верхнего уровня: tta.penstock.data.iserver.OrderBlotter, который содержит список tta.penstock.data.iserver.OrderResponseWrappers, который расширяет com.eztech.OrderResponse.Все двойные поля содержатся в com.eztech.OrderResponse.

Мой код модульного теста выполняет следующие действия:

JAXBContext context = JAXBContext.newInstance(new Class[] { OrderBlotter.class, OrderResponseWrapper.class, OrderResponse.class});

Marshaller marshaller = context.createMarshaller();
StringWriter stringWriter = new StringWriter();
marshaller.marshal(blotter, stringWriter);
System.out.println("result xml=\n" + stringWriter.toString());

Но двойные значения по-прежнему не обрабатываются XmlAdapter.Я знаю, что упускаю что-то простое, но я не уверен, что это такое.

Ответы [ 2 ]

13 голосов
/ 10 ноября 2010

Вы можете использовать XmlAdapter:

XmlAdapter

package example;

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class DoubleAdapter extends XmlAdapter<Double, Double>{

    @Override
    public Double unmarshal(Double v) throws Exception {
        return v;
    }

    @Override
    public Double marshal(Double v) throws Exception {
       if(Double.MAX_VALUE == v) {
           return null;
       } else {
           return v;
       }
    }

}

Объект модели

package example;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement
public class Root {

    @XmlJavaTypeAdapter(DoubleAdapter.class)
    public Double maxDouble = Double.MAX_VALUE;

    @XmlJavaTypeAdapter(DoubleAdapter.class)
    public Double aDouble = 123d;

}

Демонстрационный код

package example;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(new Root(), System.out);
    }

}

ОБНОВЛЕНИЕ

Предложение StaxMan - хорошее. Если вы укажете следующую аннотацию уровня пакета, вы можете избежать необходимости индивидуального аннотирования всех свойств Double

package-info.java

@XmlJavaTypeAdapters({
    @XmlJavaTypeAdapter(type=Double.class, value=DoubleAdapter.class)
})
package example;

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
0 голосов
/ 10 ноября 2010

Написать геттер, который возвращает ноль вместо Double.MAX_VALUE?(если тип 'double', сначала нужно изменить его на 'Double', чтобы разрешить нулевые значения).Поскольку JAXB по умолчанию игнорирует запись нулей, это должно достичь того, что вы пытаетесь сделать.Это предполагает, что вы можете изменить унаследованный класс.

...