Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic property name for Jackson serialization

Tags:

java

json

jackson

I have a number of classes I'm trying to serialize to JSON. They're very similar, so I'm wondering if there's a better way to do this than creating 3 very-near-identical classes each time this pattern shows up:

public class SomethingFoo {
  @JsonProperty("foo")
  Identifier foo

  // other properties
}

public class SomethingBar {
  @JsonProperty("bar")
  Identifier bar

  // other properties
}

public class SomethingBaz {
  @JsonProperty("baz")
  Identifier baz

  // other properties
}

Identifier is a class that only contains one field:

public class Identifier {
  @JsonProperty("name")
  String name = "";
}

What I would like to do, is change Identifier to something like:

public class Identifier {
  @JsonProperty("name")
  String name = "";

  @JsonIgnore
  IdentifierType type;
}

public Enum IdentifierType {
  FOO, BAR, BAZ;
}

I would then like to use the 'type' field, within Identifier, to change the name of the Identifier field in the objects that contain those Identifiers.

I would then like to do replace SomethingFoo, SomethingBar, and SomethingBaz with this:

public class Something {
  @JsonProperty(??????)
  Identifier name

  // other properties
}

I would like the property name of Something.identifier to be "foo", "bar", or "baz", depending on the value of Identifier.type.

Alternatively, I could also sub-class Identifier, rather than use an Enum.

The problem is that I'm trying to use a value within an object (or the type of the object, if sub-classes are used) to inform the property name in the Identifier's containing class. So I don't know if what I want to do is even possible without changing every class that contains an Identifier.

Edit:

The problem is I want 'Something' to be Serialized as one of these (Based on Identifier's enum type (or subclass, if that's a better way to accomplish this)):

{
  "foo" : { 
     "name" : "blahblahblah"
  }
}

{
  "bar" : { 
     "name" : "blahblahblah"
  }
}

{
  "baz" : { 
     "name" : "blahblahblah"
  }
}
like image 479
SlimyTadpole Avatar asked Sep 16 '14 20:09

SlimyTadpole


People also ask

What is Jackson object serialization?

Jackson is a solid and mature JSON serialization/deserialization library for Java. The ObjectMapper API provides a straightforward way to parse and generate JSON response objects with a lot of flexibility. This article discussed the main features that make the library so popular.

Does Jackson use serializable?

Introduction of ObjectMapper Class jackson. databind package and can serialize and deserialize two types of objects: Plain Old Java Objects (POJOs)

What is JsonProperty annotation?

@JsonProperty is used to mark non-standard getter/setter method to be used with respect to json property.


1 Answers

This can be done using JsonSerializer with your custom implementation. Please refer to below code.

 @JsonSerialize(using = Term.TermSerializer.class)
 public class Term {

//@JsonProperty("field")
private String field;

public Term() {

}

public Term(String field){
    this.field = field;
}

public String getField() {
    return field;
}

public void setField(String field) {
    this.field = field;
}

public static class TermSerializer extends JsonSerializer<Term> {
    @Override public void serialize(Term value, JsonGenerator jsonGenerator, SerializerProvider provider)
        throws IOException {
        jsonGenerator.writeStartObject();
        jsonGenerator.writeStringField("price", value.getField());// dynamic field name
        jsonGenerator.writeEndObject();
    }
}

public static void main(String[] args){
    Term term = new Term("color");
    ObjectMapper mapper = new ObjectMapper();
    mapper.enable(SerializationFeature.INDENT_OUTPUT);
    mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
    String jsonString = null;
    try {
        jsonString = mapper.writeValueAsString(term);
    } catch (JsonProcessingException e) {
        e.printStackTrace();
    }
    System.out.println(jsonString);
}

}

like image 149
tarush grover Avatar answered Sep 28 '22 02:09

tarush grover