jaxb marshall Boolean as Integer(0,1)问题

时间:2012-02-21 15:57:30

标签: jaxb integer boolean marshalling unmarshalling

我的问题看起来很简单,但我无法在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>,它将true / false转换为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适配器的marshal / unmarshal方法中放入了简单的打印消息,并试图编组/解组这种对象。

我看到没有类型声明的unmarshal方法被调用但是marshal却没有。 使用类型声明只调用marshal。

帮助?? 如何编组/解组我的布尔值到{1,0}并可能在编组的xml中删除xsi:类型?

编辑 - 这是我用来测试marshal / unmarshal的代码:

    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 个答案:

答案 0 :(得分:1)

使用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;
    }

}

答案 1 :(得分:0)

发现了问题:

CXF pom使该项目使用jaxb-impl版本2.1.0。 没有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>