Skip to content

Instantly share code, notes, and snippets.

@bseib
Created November 29, 2015 18:41
Show Gist options
  • Save bseib/095a6809c9e9be34d7b9 to your computer and use it in GitHub Desktop.
Save bseib/095a6809c9e9be34d7b9 to your computer and use it in GitHub Desktop.
Jackson interface serialization experiment
package example.rs;
import org.codehaus.jackson.map.annotate.JsonSerialize;
@JsonSerialize(as=Description.class)
public interface Description {
public String getColor();
public String getName();
}
package example.rs;
import org.codehaus.jackson.map.annotate.JsonSerialize;
@JsonSerialize(as=Dimensions.class)
public interface Dimensions {
public int getHeight();
public int getWidth();
}
package example.rs;
import java.io.IOException;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
public class TestJacksonSerialization {
final static Thing SAMPLE_THING = new Thing(1, 2, "purple", "Eggplant");
static public void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(System.out, SAMPLE_THING);
// output is:
// {"name":"Eggplant","color":"purple"}
//
// But if you swap the interface order in Thing class to be:
// Thing implements Dimensions, Description
//
// then the output is:
// {"height":1,"width":2}
//
// Looks like Jackson chooses the first @JsonSerialize() it finds.
}
}
package example.rs;
public class Thing implements Description, Dimensions {
private int height;
private int width;
private String color;
private String name;
public Thing(int height, int width, String color, String name) {
super();
this.height = height;
this.width = width;
this.color = color;
this.name = name;
}
public int getHeight() {
return height;
}
public int getWidth() {
return width;
}
public String getColor() {
return color;
}
public String getName() {
return name;
}
}
@konstantinosraptis91
Copy link

Hello, have you found any solution for this?

@bseib
Copy link
Author

bseib commented Jan 24, 2021

No I don't know a workaround. But re-reading the stackoverflow thread that prompted this gist, maybe try the following:

Create two classes that extend a base class, like this:

public class Thing { ... as above ... }  // base class, implements none
public class ThingA extends Thing implements Description, Dimensions { ... empty ... }
public class ThingB extends Thing implements Dimensions, Description { ... empty ... }

The ThingA and ThingB classes are identical since they extend the same base class. But the implements declarations order are swapped.

In theory, Jackson should choose the first interface in declaration when it renders the JSON. You just have to choose either ThingA or ThingB to force what you want in the moment. Kinda ugly if it works, but that's how workarounds go.

If you try it out, please share the outcome here. 😄

@bseib
Copy link
Author

bseib commented Jan 24, 2021

And perhaps ThingA and ThingB need only implement the one interface that they represent, like:

public class ThingAsDescription extends Thing implements Description { }
public class ThingAsDimensions extends Thing implements Dimensions { }

@konstantinosraptis91
Copy link

konstantinosraptis91 commented Jan 24, 2021

Hmm smart but (I will agree) ugly approach. I will give it a shot, I think it will work. The question is how you can tell Jackson which interface to choose every time. I have seen a couple of approaches that mentioned in this stackoveflow thread . I tried the second one with the json views but it didnt work for me and the reason is (I think), because I am using Javalin and I am not sure how to add the @JsonView annotation in the Rest Controller. I havent managed to implement the 1st solution with a custom serializer, because I dont have much experiance in custom serialization, but I am trying to implement a custom serializer and see how it goes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment