jaxb Marshall Boolean as Integer (0,1) задачи - PullRequest
2 голосов
/ 21 февраля 2012

Моя проблема кажется довольно простой, но я не смог найти ничего похожего на stackoverflow.

Я использую jaxb для маршалла / демаршаллинга этого объекта:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "")
@XmlRootElement(name = "root")
public class MyJaxbObject implements Serializable
{

    @XmlElement(name = "DELETE")
    @XmlJavaTypeAdapter(BooleanIntAdapter.class)
    private Boolean delete;

    @XmlElement(name = "message")
    private String message;

     constructors.. getters... setters...
}

Мой BooleanAdapter - это простой XmlAdapter<Integer, Boolean>, который превращает истину / ложь в 1/0 и обратно.

Немаршаллинг работает, а маршаллинг - нет. это всегда приводит к этому:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
    <DELETE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.or/2001/XMLSchema" xsi:type="xs:boolean">true</DELETE>
    <message>***DONE***</message>
</root>

Когда я изменяю конфигурацию элемента xml на @XmlElement(name = "DELETE",type = Boolean.class) сбой демаршаллинга логического значения, и маршаллинг дает это:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
    <DELETE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">1</DELETE>
    <message>***DONE***</message>
</root>

Я поместил простые печатные сообщения в методы маршала / демаршала адаптера xml и попытался маршалировать / демаршировать этот тип объекта.

Я видел, что без объявления типа вызывается unmarshal метод, а marshal - нет. С объявлением типа вызывается только маршал.

Помощь ?? Как я могу выполнить маршалинг / демаршалирование моего логического значения в / из {1,0} и, возможно, избавиться от типа xsi: type в маршаллированном xml?

Редактировать - это код, который я использовал для проверки маршала / демаршала:

    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
    JAXBContext context = javax.xml.bind.JAXBContext.newInstance("my.package.classes");
    Unmarshaller unmarshal = context.createUnmarshaller();
    Marshaller marshal = context.createMarshaller();
    marshal.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

    String str = "<root><DELETE>1</DELETE><message>***DONE***</message></root>";
    DocumentBuilder builder = docBuilderFactory.newDocumentBuilder();
    Document d = null;
    d = builder.parse(new InputSource(new StringReader(str)));

    MyJaxbObject myJaxUnmarsh = unmarshal.unmarshal(d.getFirstChild(), MyJaxbObject.class).getValue();
    System.out.println(myJaxUnmarsh.getMessage() + " , " + myJaxUnmarsh.getDelete());

    MyJaxbObject myJax = new MyJaxbObject();
    myJax.setDelete(true);
    myJax.setMessage("***DONE***");
    marshal.marshal(myJax, System.out);

Ответы [ 2 ]

1 голос
/ 21 февраля 2012

При следующей реализации BooleanIntAdapter:

BooleanIntAdapter

package forum9380680;

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

public class BooleanIntAdapter extends XmlAdapter<Integer, Boolean> {

    @Override
    public Boolean unmarshal(Integer v) throws Exception {
        return v.equals(1);
    }

    @Override
    public Integer marshal(Boolean v) throws Exception {
        if(v) {
            return 1;
        } else {
            return 0;
        }
    }

}

выход

Я получаю следующий вывод:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <DELETE>1</DELETE>
   <message>***DONE***</message>
</root>
<Ч />

Ниже приведен код, который я использовал:

Демо

package forum9380680;

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(MyJaxbObject.class);

        MyJaxbObject object = new MyJaxbObject();
        object.setDelete(true);
        object.setMessage("***DONE***");

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(object, System.out);
    }

}

MyJaxbObject

package forum9380680;

import java.io.Serializable;

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

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "")
@XmlRootElement(name = "root")
public class MyJaxbObject implements Serializable
{

    @XmlElement(name = "DELETE")
    @XmlJavaTypeAdapter(BooleanIntAdapter.class)
    private Boolean delete;

    @XmlElement(name = "message")
    private String message;

    public Boolean getDelete() {
        return delete;
    }

    public void setDelete(Boolean delete) {
        this.delete = delete;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

}
0 голосов
/ 22 февраля 2012

обнаружил проблему:

CXF pom заставляет проект использовать версию 2.1.0 jaxb-impl.Без CXF проект использует JDK по умолчанию, который в моем случае был 2.1.10.см .: http://jaxb.java.net/guide/Which_JAXB_RI_is_included_in_which_JDK_.html

Я добавил следующее в управление зависимостями, чтобы решить проблему

<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.2.5</version>
    <type>jar</type>
    <scope>compile</scope>
</dependency>
...