Reputation: 311
I have this JSON file
{
"personal": {
"name": "John Doe",
"age": "28",
"gender": "male",
}
}
This is the POJO I want to parse it to
public class customerInfo{
private String infoType;
private Map<String, String>;
}
The reason I want to use this POJO because the JSON file could also be
{
"address": {
"street": "123 main st",
"state": "md",
"zipcode": "21228"
}
}
This is what I tried but it didn't work
customerInfo customer = mapper.readValue(new File("jsonTestFile.json"), customerInfo.class);
Any help please? Thank you!
EDIT: so I want infoType to map to personal or address. And the Map should be , and so on
Upvotes: 2
Views: 103
Reputation: 208974
You could accomplish this with a custom deserializer and serializer.
Deserializer could look something like
public class CustomerInfoDeserializer extends JsonDeserializer<CustomerInfo> {
private final Set<String> allowedFields;
public CustomerInfoDeserializer(String... allowedFields) {
Set<String> allowed = new HashSet<>(Arrays.asList(allowedFields));
this.allowedFields = Collections.unmodifiableSet(allowed);
}
@Override
public CustomerInfo deserialize(JsonParser jp, DeserializationContext dc)
throws IOException, JsonProcessingException {
JsonNode node = jp.getCodec().readTree(jp);
String field = node.fieldNames().next();
if (!allowedFields.contains(field)) {
throw new JsonMappingException("Field '" + field + "' not allowed");
}
CustomerInfo info = new CustomerInfo();
info.setInfoType(field);
JsonNode dataNode = node.get(field);
for (Iterator<String> it = dataNode.fieldNames(); it.hasNext();) {
String name = it.next();
info.addProperty(name, dataNode.get(name).asText());
}
return info;
}
}
Serializer would simply be
public class CustomerInfoSerializer extends JsonSerializer<CustomerInfo> {
@Override
public void serialize(CustomerInfo c, JsonGenerator jg, SerializerProvider sp)
throws IOException, JsonProcessingException {
jg.writeStartObject();
jg.writeObjectField(c.getInfoType(), c.getProperties());
jg.writeEndObject();
}
}
And CustomerInfo
class
public class CustomerInfo {
private String infoType;
private final Map<String, String> properties = new HashMap<>();
public void addProperty(String name, String value) {
properties.put(name, value);
}
public Map<String, String> getProperties() {
return properties;
}
public String getInfoType() {
return infoType;
}
public void setInfoType(String infoType) {
this.infoType = infoType;
}
}
Test
public static void main(String[] args) throws Exception {
final String personal
= "{"
+ " \"personal\": {"
+ " \"name\": \"John Doe\","
+ " \"age\": \"28\","
+ " \"gender\": \"male\""
+ " }"
+ "}";
final String address
= "{"
+ " \"address\": {"
+ " \"street\": \"123 main st\","
+ " \"state\": \"md\","
+ " \"zipcode\": \"21228\""
+ " }"
+ "}";
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(
CustomerInfo.class,
new CustomerInfoDeserializer("personal", "address")
);
module.addSerializer(CustomerInfo.class, new CustomerInfoSerializer());
mapper.registerModule(module);
CustomerInfo info = mapper.readValue(personal, CustomerInfo.class);
System.out.println(mapper.writeValueAsString(info));
info = mapper.readValue(address, CustomerInfo.class);
System.out.println(mapper.writeValueAsString(info));
}
See More:
Upvotes: 1
Reputation: 232
If the two json you posted are the only possible, your class should look like this insteed :
public class CustomerInfo {
private Address address;
private Personal personal;
}
And you should also create these two classes :
public class Address {
private String street;
private String state;
private String zipcode;
}
public class Personal {
private String name;
private String age;
private String gender;
}
It should work, then you only need to check wich one of address or personal is null, so that you can know wich one to use.
I hope you understood how to use Jackson library now. If it is not clear, please ask me for help.
Upvotes: 0