jaxb2Marshaller 将 XML 解组为空字节数组

发布于 2024-11-05 11:08:40 字数 3622 浏览 0 评论 0原文

问题就在这里。 我正在使用 Spring 3.0.4 创建一个 REST Web 服务(实际上我是一个新手)。 我想通过 hibernate 持久保存一个由客户端作为 XML 表示形式传递的对象。为了完成这个任务,我使用 jaxb2。

客户端发送的对象是一个具有两个子对象的节点,即数据和元数据。

问题是,当客户端发送其 XML 时,SIUserData 被解组到不可预测的 byte[] 数组中:有时输入的一部分被删除,有时它只是空的。

例如,此输入

<.SINode>
    <.SIUserMeta>a lot of meta<./SIUserMeta>
    <.SIUserData>BBB<./SIUserData>
<./SINode>

在具有空 StorageInterfaceData 内容属性的对象中解组。

我相信这个问题会影响 byte[] 的处理,因为我尝试更改 String 中的 StorageInterfaceData 内容属性的类型,最终一切正常:S 。

它遵循代码。

node

@Entity
@Table(name="sinode")
@XmlRootElement(name="SINode")
public class StorageInterfaceNode extends BulkObject  implements Serializable{


    private Integer id;
    private String name;
    private StorageInterfaceMetadata metadata;
    private StorageInterfaceData data;

    public StorageInterfaceNode() {
        super();
        // TODO Auto-generated constructor stub
    }

    public StorageInterfaceNode(Integer id, String name, StorageInterfaceMetadata metadata,
            StorageInterfaceData data) {
        super();
        this.id = id;
        this.name = name;
        this.metadata = metadata;
        this.data = data;
    }

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="id", unique=true, nullable=false)
    @XmlTransient
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @XmlTransient
    @Column(name="name", unique=true)
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    @OneToOne(cascade= CascadeType.ALL)
    @XmlElement(name="SIUserMeta")
    public StorageInterfaceMetadata getMetadata() {
        return metadata;
    }
    public void setMetadata(StorageInterfaceMetadata metadata) {
        this.metadata = metadata;
    }

    @OneToOne(cascade= CascadeType.ALL)
    @XmlElement(name="SIUserData")
    public StorageInterfaceData getData() {
        return data;
    }
    public void setData(StorageInterfaceData data) {
        this.data = data;
    }

}

data

@Entity
@Table(name="data")
public class StorageInterfaceData extends BulkObject implements Serializable{


    private Integer id;
    private String dataName;
    private byte[] content;

    public StorageInterfaceData() {
        super();
        // TODO Auto-generated constructor stub
    }

    public StorageInterfaceData(byte[] content) {
        super();
        this.content = content;
    }

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="id", unique=true)
    @XmlTransient
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Column(name="name", unique=true, nullable=false)
    @XmlTransient
    public String getDataName() {
        return dataName;
    }

    public void setDataName(String dataName) {
        this.dataName = dataName;
    }

    @Column(name="content", nullable=false)
    @XmlValue
    public byte[] getContent() {
        return content;
    }

    public void setContent(byte[] content) {
        this.content = content;
    }
}

bulkobject

@XmlTransient
public class BulkObject {

    private Integer id;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

}

元数据类被省略,以免过于冗长。 请问有人可以清理一下吗?

here's the problem.
I'm using Spring 3.0.4 to create a rest web service (and actually I am a novice).
I want to persist an object via hibernate passed by the client as an XML representation. To accomplish this task I use jaxb2.

The object the client send is a node having two sons objects, namely data and metadata.

the problem is that when the client sends its XML the SIUserData is unmarshalled in an umpredictable byte[] array: sometimes a part of the imput is cut away and sometimes it is simply empty.

for example this input

<.SINode>
    <.SIUserMeta>a lot of meta<./SIUserMeta>
    <.SIUserData>BBB<./SIUserData>
<./SINode>

is unmarshalled in an object with an empty StorageInterfaceData content attribute.

I believe the problem affects the handling of byte[] since I tryied to change the type of StorageInterfaceData content attribute in a String end everything works fine :S .

It follows the code.

node

@Entity
@Table(name="sinode")
@XmlRootElement(name="SINode")
public class StorageInterfaceNode extends BulkObject  implements Serializable{


    private Integer id;
    private String name;
    private StorageInterfaceMetadata metadata;
    private StorageInterfaceData data;

    public StorageInterfaceNode() {
        super();
        // TODO Auto-generated constructor stub
    }

    public StorageInterfaceNode(Integer id, String name, StorageInterfaceMetadata metadata,
            StorageInterfaceData data) {
        super();
        this.id = id;
        this.name = name;
        this.metadata = metadata;
        this.data = data;
    }

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="id", unique=true, nullable=false)
    @XmlTransient
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @XmlTransient
    @Column(name="name", unique=true)
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    @OneToOne(cascade= CascadeType.ALL)
    @XmlElement(name="SIUserMeta")
    public StorageInterfaceMetadata getMetadata() {
        return metadata;
    }
    public void setMetadata(StorageInterfaceMetadata metadata) {
        this.metadata = metadata;
    }

    @OneToOne(cascade= CascadeType.ALL)
    @XmlElement(name="SIUserData")
    public StorageInterfaceData getData() {
        return data;
    }
    public void setData(StorageInterfaceData data) {
        this.data = data;
    }

}

data

@Entity
@Table(name="data")
public class StorageInterfaceData extends BulkObject implements Serializable{


    private Integer id;
    private String dataName;
    private byte[] content;

    public StorageInterfaceData() {
        super();
        // TODO Auto-generated constructor stub
    }

    public StorageInterfaceData(byte[] content) {
        super();
        this.content = content;
    }

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="id", unique=true)
    @XmlTransient
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Column(name="name", unique=true, nullable=false)
    @XmlTransient
    public String getDataName() {
        return dataName;
    }

    public void setDataName(String dataName) {
        this.dataName = dataName;
    }

    @Column(name="content", nullable=false)
    @XmlValue
    public byte[] getContent() {
        return content;
    }

    public void setContent(byte[] content) {
        this.content = content;
    }
}

bulkobject

@XmlTransient
public class BulkObject {

    private Integer id;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

}

metadata class is omitted not to be too verbose.
Can anyone clear the thing please?

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

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

发布评论

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

评论(1

故人如初 2024-11-12 11:08:40

好吧,我想我明白了。

我真的不知道为什么,但在解组过程中,JAXB2 故意假设我的 SIUserData 标记中的内容是用 base64 编码的。
我用纯文本进行了测试,但返回的内容对我来说毫无意义。

例如,我在 SIUserData 标签内编写了“大量数据”(文本),并发布了节点。当我拿回来后,我读到了“alotofda”,这让我有点不安。我可以理解空格消失了,但为什么要剪掉最后的“ta”?!从我的角度来看,处理 byte[] 时存在一些问题。

我错了,事情是这样的:
对于应用程序来说,“大量数据”是 Base64 编码的输入。 JAXB2在内部处理它执行解码并获得“jZ-°Z”。当我使用 GET 请求返回时,JAXB2 执行获取“alotofda”的逆操作。出现这个问题是因为“大量数据”不是符合 Base64 的字符串。
我在上面的问题中提到的“BBB”字符串也会发生同样的情况。
如果我使用真正的 Base64 编码数据,一切都会完美运行。这是我的幸运,因为这是我管理数据的方式。
为了完整起见,有人知道如何使用不同格式处理 XML 中的数据吗?如何克服这种 JAXB2 行为?

ok, I think I get the point.

I really don't know why, but during the unmarshalling procedure JAXB2 assumes deliberately that the stuff within my SIUserData tags are encoded in base64.
I made my test writing plain text and what it was returned was something senseless to me.

For example, I wrote "a lot of data" (textually) within SIUserData tags and I POSTed the node. Once I GET it back I read "alotofda" and it made me a little upset. I could understand that the white spaces disappeared but why should it cut the final "ta"?! From my point of view there was some problems in handling byte[].

I was wrong and this is how the thing goes:
For the application "a lot of data" is a base64 encoded input. JAXB2 handles it internally performing a decoding and obtaining "jZ-¡÷Z". When I ask it back with a GET, JAXB2 performs the inverse operation obtaining "alotofda". The problem pops up because "a lot of data" is not a base64 compliant string.
The same thing happens with the "BBB" string I mentioned above in the question.
If I use real base64 encoded data everything works perfectly. It is my luck, since it is the way I have to manage my data.
Just for completeness, anyone knows how to handle data in XML using different formats? And how to overcome this JAXB2 behaviour?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文