stenwolf
stenwolf

Reputation: 311

how to parse this JSON file using jackson?

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

Answers (2)

Paul Samsotha
Paul Samsotha

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

victorleduc
victorleduc

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

Related Questions