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