Reputation: 441
We have two Pojo files.
Person {
String name;
int age;
String address;
String phoneNo;
boolean isMarried;
}
and
OtherPerson {
//mandatory fields are name and age
String name_other;
int age_other;
//other fields
Map<String, Object> otherFields;
}
and a json file which defines the mapping between the fields using name
mappingJson {
"name":"name_other",
"age":"age_other",
"address":"address_other",
"phoneNo":"phoneno_other",
"isMarried":"ismarried_other"
}
Please let me know the best approach to convert Person to OtherPerson. So that the mandatory fields map to name_other and age_other while the other fields should be added to the map(otherFields)
It may be
Person->Person(json)->OtherPerson
Or Person->OtherPerson.
EDIT: "Use case: We have an API which used to accepts a POJO 'A' but now it needs to accept POJO 'B' as an input argument. This POJO needs to get converted into POJO 'A' which can then be used for persisting into the database. Also POJO 'B' is not under our control"
Upvotes: 0
Views: 5036
Reputation: 114
That's a perfect fit for Jackson Converter! :) It could work like this:
class OtherPerson {
@JsonProperty("name")
public String name_other;
@JsonProperty("age")
public int age_other;
Map<String, Object> otherFields = new LinkedHashMap<>();;
@JsonAnySetter
public void add(String key, Object value) {
otherFields.put(key, value);
}
}
// ...
Person person = new Person();
person.name = "Avinash";
person.age = 25;
person.address = "Mumbai";
person.phoneNo = "910731";
person.isMarried = true; // :( sorry ladies!
// ...
ObjectMapper mapper = new ObjectMapper();
// If we cannot put @JsonAutoDetect on top of Person.class,
// we need to add handling of non-public fields
// since Person seems to neither have public fields nor setters
mapper.configOverride(Person.class)
.setVisibility(JsonAutoDetect.Value.defaultVisibility()
.withFieldVisibility(JsonAutoDetect.Visibility.NON_PRIVATE));
OtherPerson other = mapper.convertValue(person, OtherPerson.class);
Voilà!
Upvotes: 4
Reputation: 13859
I personally would do this without JSON. It's my understanding that some fields in the Map
are optional while name and age are mandatory. In the case of the optional content, I would use the Ternary
operator to create the person object. This allows you to add some default value if the optional field is not available.
Main
import java.util.HashMap;
import java.util.Map;
/**
*
* @author blj0011
*/
public class JavaApplication30 {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Map<String, Object> map1 = new HashMap();
map1.put("address", "123 Hello Street");
map1.put("phoneNo", "555-555-5555");
map1.put("isMarried", true);
OtherPerson otherPerson = new OtherPerson("John Doe", 22, map1);
Map<String, Object> map2 = new HashMap();
map2.put("address", "4456 Bye Road");
map2.put("isMarried", false);
OtherPerson otherPerson2 = new OtherPerson("Jane Doe", 21, map2);
Person person1 = new Person(otherPerson.getName_other(), otherPerson.getAge_other(),
otherPerson.getOtherFields().containsKey("address") ? otherPerson.getOtherFields().get("address").toString(): "",
otherPerson.getOtherFields().containsKey("phoneNo") ? otherPerson.getOtherFields().get("phoneNo").toString(): "",
otherPerson.getOtherFields().containsKey("isMarried") ? Boolean.valueOf(otherPerson.getOtherFields().get("isMarried").toString()): false);
System.out.println(person1);
Person person2 = new Person(otherPerson2.getName_other(), otherPerson2.getAge_other(),
otherPerson2.getOtherFields().containsKey("address") ? otherPerson2.getOtherFields().get("address").toString(): "",
otherPerson2.getOtherFields().containsKey("phoneNo") ? otherPerson2.getOtherFields().get("phoneNo").toString(): "",
otherPerson2.getOtherFields().containsKey("isMarried") ? Boolean.valueOf(otherPerson2.getOtherFields().get("isMarried").toString()): false);
System.out.println(person2);
}
}
Person
/**
*
* @author blj0011
*/
public class Person {
private String name;
private int age;
private String address;
private String phoneNo;
private boolean isMarried;
public Person(String name, int age, String address, String phoneNo, boolean isMarried) {
this.name = name;
this.age = age;
this.address = address;
this.phoneNo = phoneNo;
this.isMarried = isMarried;
}
public boolean isIsMarried() {
return isMarried;
}
public void setIsMarried(boolean isMarried) {
this.isMarried = isMarried;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhoneNo() {
return phoneNo;
}
public void setPhoneNo(String phoneNo) {
this.phoneNo = phoneNo;
}
@Override
public String toString() {
return "Person{" + "name=" + name + ", age=" + age + ", address=" + address + ", phoneNo=" + phoneNo + ", isMarried=" + isMarried + '}';
}
}
OtherPerson
/**
*
* @author blj0011
*/
public class OtherPerson {
//mandatory fields are name and age
private String name_other;
private int age_other;
//other fields
private Map<String, Object> otherFields;
public OtherPerson(String name_other, int age_other, Map<String, Object> otherFields) {
this.name_other = name_other;
this.age_other = age_other;
this.otherFields = otherFields;
}
public Map<String, Object> getOtherFields() {
return otherFields;
}
public void setOtherFields(Map<String, Object> otherFields) {
this.otherFields = otherFields;
}
public String getName_other() {
return name_other;
}
public void setName_other(String name_other) {
this.name_other = name_other;
}
public int getAge_other() {
return age_other;
}
public void setAge_other(int age_other) {
this.age_other = age_other;
}
}
Output
Person{name=John Doe, age=22, address=123 Hello Street, phoneNo=555-555-5555, isMarried=true}
Person{name=Jane Doe, age=21, address=4456 Bye Road, phoneNo=, isMarried=false}
As you can see in the output OtherPerson2 did not have a phone number. Empty string was use as the default value.
Upvotes: 0