Reputation: 67370
I'm using Jersey 1.17 with com.sun.jersey.api.json.POJOMappingFeature
set to true and I'm POSTing an object that looks like this:
import com.fasterxml.jackson.annotation.JsonIgnore;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
@XmlRootElement
public class ByteArrayWithOverloadedSetterObject {
private byte[] data;
public void setData(byte[] data) {
this.data = data;
}
@XmlTransient
@JsonIgnore
public void setData(String data) {
this.data = data.getBytes();
}
public byte[] getData() {
return data;
}
}
My Resource has this method:
@POST
@Path("postByteArrayWithOverloadedSetterObject")
public byte[] sendByteArrayWithOverloadedSetterObject(ByteArrayWithOverloadedSetterObject byteArrayWithOverloadedSetterObject) {
if (byteArrayWithOverloadedSetterObject.getData() == null) {
log.warn("data was null!");
}
return byteArrayWithOverloadedSetterObject.getData();
}
And my client side unit tests are written like this:
@Test
public void whenSendingStringDataThenGetDataBack() {
ByteArrayWithOverloadedSetterObject byteArrayWithOverloadedSetterObject = new ByteArrayWithOverloadedSetterObject();
byteArrayWithOverloadedSetterObject.setData("foobar");
byte[] data = new AuthClient().postJaxbToUrl(RestApiUriBuilder.TEST_REST_PATH + "/postByteArrayWithOverloadedSetterObject", byteArrayWithOverloadedSetterObject, byte[].class);
assertNotNull(data);
}
@Test
public void whenSendingByteDataThenGetDataBack() {
ByteArrayWithOverloadedSetterObject byteArrayWithOverloadedSetterObject = new ByteArrayWithOverloadedSetterObject();
byteArrayWithOverloadedSetterObject.setData(new byte[]{0, 1, 1, 0});
byte[] data = new AuthClient().postJaxbToUrl(RestApiUriBuilder.TEST_REST_PATH + "/postByteArrayWithOverloadedSetterObject", byteArrayWithOverloadedSetterObject, byte[].class);
assertNotNull(data);
}
Both of these tests are failing with a message that says "postByteArrayWithOverloadedSetterObject returned a response status of 204 No Content" and the server is logging "data was null!" for each. Why isn't the byte array data being serialized over the wire? I'm sending this as JSON.
If I comment out the @XmlTransient
/@JsonIgnore
annotations, I get this error: "java.lang.RuntimeException: Conflicting setter definitions for property "data"".
In my real situation, I can't easily modify the API of ByteArrayWithOverloadedSetterObject
. But since this is just a test, I can see that things work correctly if I rename the second setter and the object becomes this:
import com.fasterxml.jackson.annotation.JsonIgnore;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
@XmlRootElement
public class ByteArrayWithOverloadedSetterObject {
private byte[] data;
public void setData(byte[] data) {
this.data = data;
}
@XmlTransient
@JsonIgnore
public void setData2(String data) { //RENAME HERE. Now tests pass.
this.data = data.getBytes();
}
public byte[] getData() {
return data;
}
}
Since I can't change the API of ByteArrayWithOverloadedSetterObject
, is there any other work around to this?
Upvotes: 6
Views: 2492
Reputation: 67370
This is the solution:
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
@XmlRootElement
public class ByteArrayWithOverloadedSetterObject {
private byte[] data;
@JsonProperty //I ADDED THIS
public void setData(byte[] data) {
this.data = data;
}
@XmlTransient
@JsonIgnore
public void setData(String data) {
this.data = data.getBytes();
}
public byte[] getData() {
return data;
}
}
Now my tests pass.
Upvotes: 8