jaxb2Marshaller 将 XML 解组为空字节数组
问题就在这里。 我正在使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好吧,我想我明白了。
我真的不知道为什么,但在解组过程中,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?