jaxb marshall 布尔值作为整数 (0,1) 问题

发布于 2025-01-07 07:59:25 字数 2609 浏览 1 评论 0原文

我的问题看起来很简单,但我无法在 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,它将 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 方法中,并尝试 marshal/unmarshal 这种对象。

我看到没有类型声明 unmarshal 方法被调用,但 marshal 没有被调用。 通过类型声明,仅调用元帅。

帮助?? 如何将布尔值编组/解组到 {1,0} 或从 {1,0} 编组/取消编组,并可能删除编组 xml 中的 xsi:type ?

编辑 - 这是我用来测试 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);

My problem seems pretty simple, yet I was unable to find anything exactly like it on stackoverflow.

I'm using jaxb to marshall/unmarshall this object:

@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...
}

My BooleanAdapter is a simple XmlAdapter<Integer, Boolean> that turns true/false to 1/0 and back.

Unmarshalling works, but marshalling does not. it always yeilds this:

<?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>

When I change the xml element config to @XmlElement(name = "DELETE",type = Boolean.class) unmarshalling of the boolean fails and marshalling yields this:

<?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>

I put simple print messages in the marshal/unmarshal methods of the xml adapter and tried to marshal/unmarshal this kind of object.

I saw that without type declaration unmarshal method is called but marshal is not.
With the type declaration only marshal is called.

Help??
How can I marshal/unmarshal my Boolean to/from {1,0} and possibly get rid of the xsi:type in the marshalled xml?

Edit - this is the code i used to test 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);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

动次打次papapa 2025-01-14 07:59:25

通过以下 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;
        }
    }

}

Output

我得到以下输出:

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

下面是我使用的其余代码:

Demo

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

}

With the following implementation of 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;
        }
    }

}

Output

I get the following output:

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

Below is the rest of the code I used:

Demo

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

}
万水千山粽是情ミ 2025-01-14 07:59:25

发现问题:

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>

found the problem:

CXF pom makes the project use jaxb-impl version 2.1.0.
Without CXF the project uses the JDK default which was 2.1.10 in my case.
see:
http://jaxb.java.net/guide/Which_JAXB_RI_is_included_in_which_JDK_.html

I added the following under dependency management to fix the problem

<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.2.5</version>
    <type>jar</type>
    <scope>compile</scope>
</dependency>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文