Home > Mobile >  Inheritance DRY response
Inheritance DRY response

Time:08-28

I have two class for external API response:

ClassA:

@JsonIgnoreProperties(ignoreUnknown = true)
@Getter
@Setter
public class ClassA {

  private SubClass subClass;

  @Getter
  @Setter
  public static class SubClass {

    Integer total;
    Integer perPage;
    List<Data> dataList;

    @Getter
    @Setter
    public static class Data {
       
      private String field1;
      private String field2;
      private int field3;
    }
  }
}

ClassB:

@JsonIgnoreProperties(ignoreUnknown = true)
@Getter
@Setter
public class ClassB {

  private SubClass subClass;

  @Getter
  @Setter
  public static class SubClass {

    Integer total;
    Integer perPage;
    List<Data> dataList;

    @Getter
    @Setter
    public static class Data {
       
      private String field1;
      private int field2;
      private Date field3;
    }
  }
}

And deserialization with ObjectMapper:

  ClassA classA =
      mapper.readValue(bodyResponse, ClassA.class);

What is the best way to get rid of duplicate code in these classes when using inheritance and later using deserialization?

CodePudding user response:

You need to make root and sub classes generic. Use TypeReference to provide which data class you expect. Take a look at below example:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.json.JsonMapper;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import java.util.Date;
import java.util.List;

public class GenericDataApp {
    public static void main(String[] args) throws JsonProcessingException {
        JsonMapper mapper = JsonMapper.builder().build();
        String srcA = "{\"subClass\":{\"total\":1,\"dataList\":[{\"field2\":\"String value\"}]}}";
        RootClass<DataA> dataA = mapper.readValue(srcA, new TypeReference<RootClass<DataA>>() {
        });
        System.out.println(dataA.getSubClass());

        String srcB = "{\"subClass\":{\"total\":1,\"dataList\":[{\"field2\":12}]}}";
        RootClass<DataB> dataB = mapper.readValue(srcB, new TypeReference<RootClass<DataB>>() {
        });
        System.out.println(dataB.getSubClass());
    }
}

@JsonIgnoreProperties(ignoreUnknown = true)
@Getter
@Setter
class RootClass<T> {

    private SubClass<T> subClass;

    @Getter
    @Setter
    @ToString
    public static class SubClass<T> {

        Integer total;
        Integer perPage;
        List<T> dataList;
    }
}

@Getter
@Setter
@ToString
class DataA {

    private String field1;
    private String field2;
    private int field3;
}

@Getter
@Setter
@ToString
class DataB {

    private String field1;
    private int field2;
    private Date field3;
}

Above code prints:

RootClass.SubClass(total=1, perPage=null, dataList=[DataA(field1=null, field2=String value, field3=0)])
RootClass.SubClass(total=1, perPage=null, dataList=[DataB(field1=null, field2=12, field3=null)])
  • Related