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;
}
}
@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