1
\$\begingroup\$

I have several json models which represent same logic model. e.g: {"title":"title1","years":"31"} and {"name":"title1","age":31}

at the moment I make 2 different classes which implement same interface

 public class NameModel implements Person {

  @SerializedName("name") private String name;
  @SerializedName("age") private int age;

  public String getName() {
    return name;
  }

  public int getAge() {
    return age;
  }
}
public class TitleModel implements Person {

  @SerializedName("title") private String title;
  @SerializedName("years") private int years;

  public String getName() {
    return title;
  }

  public int getAge() {
    return years;
  }
}
public interface Person {
  String getName();
  int getAge();
}

Is this a correct approach to unify different models to one if they are essentially same, but with different field names?

\$\endgroup\$
  • \$\begingroup\$ does it have to be gson? can you use jackson? \$\endgroup\$ – Sharon Ben Asher Feb 21 '18 at 12:33
  • \$\begingroup\$ @SharonBenAsher in most of out prject we use gson. However answer for jackson is also valuable \$\endgroup\$ – Yarh Feb 21 '18 at 12:45
1
\$\begingroup\$

in Jackson, you have the mixin feature. This allows to add or override annotations at run time.

so we have one target POJO

public class Person
{
    private String name;
    private int age;

    public void setName(String name) {
        this.name = name;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

and the mixin classes can be interfaces (they never get initialized) with matching setter method signatures and different annotations

public interface NameModel
{
    @JsonProperty("name")
    void setName(String name);
    @JsonProperty("age")
    void setAge(int age);
}

public interface TitleModel
{
    @JsonProperty("title")
    void setName(String name);
    @JsonProperty("years")
    void setAge(int age);
}

at run-time you can associate one mixin to the target class. Jackson matches properties and methods by name and takes the annotations from the mixin. overriding any from the target:

public static void main(String[] args) {
    String nameModelJson = "{\"name\":\"title1\",\"age\":31}";
    try (InputStream is = new ByteArrayInputStream(nameModelJson.getBytes())) {
        ObjectMapper mapper = new ObjectMapper();
        mapper.addMixIn(Person.class, NameModel.class);
        Person p = mapper.readValue(is, Person.class);
        System.out.println(p.name + " " + p.age);
    } catch (Exception e) {
        e.printStackTrace();
    }

    String titleModelJson = "{\"title\":\"title1\",\"years\":\"31\"}";
    try (InputStream is = new ByteArrayInputStream(titleModelJson.getBytes())) {
        ObjectMapper mapper = new ObjectMapper();
        mapper.addMixIn(Person.class, TitleModel.class);
        Person p = mapper.readValue(is, Person.class);
        System.out.println(p.name + " " + p.age);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.