Search code examples
javajsonjacksonobjectmapperfasterxml

JsonView serialization that depends on some condition/property name etc


One of my classes has 3 properties of same type. Now I'm trying to serialize it do JSON, but one of those properties needs to be serialized differently - basically one of those properties is "internal" and I need only id of it, the rest of them must be fully serialized.

What I came so far:

@NoArgsConstructor @AllArgsConstructor @Data
public static class Id {
    @JsonView(View.IdOnly.class) private long id;
}

@NoArgsConstructor @AllArgsConstructor @Data
public static class Company extends Id {
    @JsonView(View.Tx.class) private String name;
    @JsonView(View.Tx.class) private String address;
}

@NoArgsConstructor @AllArgsConstructor @Data
public static class Transaction {
    @JsonView(View.Tx.class)     private Company from;
    @JsonView(View.Tx.class)     private Company to;
    @JsonView(View.IdOnly.class) private Company createdBy;
}

public static class View {
    public interface Tx extends IdOnly {}
    public interface IdOnly {}
}

And quick test for it:

@Test
void test() throws JsonProcessingException {
    Company s = new Company("Source", "address_from");
    Company d = new Company("Destination", "address_to");
    final Transaction t = new Transaction(s, d, s);

    final ObjectMapper m = new ObjectMapper();
    System.out.println(m.writerWithDefaultPrettyPrinter().withView(View.Tx.class).writeValueAsString(t));
}

And output is:

{
  "from" : {
    "id" : 0,
    "name" : "Source",
    "address" : "address_from"
  },
  "to" : {
    "id" : 0,
    "name" : "Destination",
    "address" : "address_to"
  },
  "createdBy" : {
    "id" : 0,
    "name" : "Source",
    "address" : "address_from"
  }
}

Now, question, how can I customize serialization of createBy property? I need following output:

{
  "from" : {
    "id" : 0,
    "name" : "Source",
    "address" : "address_from"
  },
  "to" : {
    "id" : 0,
    "name" : "Destination",
    "address" : "address_to"
  },
  "createdBy" : {
    "id" : 0,
  }
}

Solution

  • Oh, I think that answer for that is very simple:

    1. Mark createdBy field with @JsonSerialize(using = CS.class)
    2. Implement custom serializer as follows:
        public static class CS extends JsonSerializer<Company> {
            @Override
            public void serialize(Company company, JsonGenerator jgen, SerializerProvider serializerProvider) throws IOException {
                jgen.writeStartObject();
                jgen.writeNumberField("id", company.getId());
                jgen.writeEndObject();
            }
        }