Daniel Kaplan
Daniel Kaplan

Reputation: 67370

I have an overloaded setter on an object, how can I tell Jackson to ignore one of them?

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

Answers (1)

Daniel Kaplan
Daniel Kaplan

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

Related Questions