2

My function needs to take an input String that can represent any kind of JSON object, clean the empty fields and transform it back to a String.

Given this input JSON, I like the doors field to be removed:

String carJson = "{ \"brand\" : \"Mercedes\", \"doors\" : \"\"}";

I was trying to work with Jackson and this post and got this:

  private static void jacksonConvert(String inputJSON) throws IOException{
    ObjectMapper mapper = new ObjectMapper();
    mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); // tried each of the 3 options. Non of them worked
    mapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    Object jacksonObj = mapper.readValue(inputJSON, Object.class);
    String json = mapper.writeValueAsString(jacksonObj);
    System.out.println(json);  // {"brand":"Mercedes","doors":""}  why "doors" is here?
}

Yet, the doors field keeps on coming out in the output...

What am I missing here?

riorio
  • 6,500
  • 7
  • 47
  • 100

2 Answers2

0

The documentation states that these enumerations are used...

to define which properties of Java Beans are to be included in serialization

However, if you're serialising to an Object Jackson will instantiate that object as a Map. Map entries are not considered properties. Therefore the Json.Include doesn't apply.

Edit

There's an existing answer about removing empty nodes (if you serialise it as a JsonNode but none of the answers strike me as particularly performant.

Andy N
  • 1,238
  • 1
  • 12
  • 30
0

Found this great working example that I will copy to here for future generations.

One small adjustment for STACIE's blog, is that I updated the block of

      else if (value instanceof ArrayNode) {
            ret.set(key, removeEmptyFields((ArrayNode)value));
        }

to also catch and remove empty arrays:

     else if (value instanceof ArrayNode) {
            if (value.size() > 0){
                ret.set(key, removeEmptyFields((ArrayNode)value));
            }
        }

And the full working code is this:

public static String removeEmptyElements(String json){

    try{

        ObjectMapper mapper = new ObjectMapper();
        ObjectNode before = mapper.readValue(json, ObjectNode.class);
        ObjectNode after = removeEmptyFields(before);

        String afterString = mapper.writeValueAsString(after);
        return afterString;
    }catch(JsonProcessingException e){
        log.error("Error while cleaning json: {}", e.getMessage());
        return json;
    }
}


private static ObjectNode removeEmptyFields(final ObjectNode jsonNode) {
    ObjectNode ret = new ObjectMapper().createObjectNode();
    Iterator<Map.Entry<String, JsonNode>> iter = jsonNode.fields();

    while (iter.hasNext()) {
        Map.Entry<String, JsonNode> entry = iter.next();
        String key = entry.getKey();
        JsonNode value = entry.getValue();

        if (value instanceof ObjectNode) {
            Map<String, ObjectNode> map = new HashMap<String, ObjectNode>();
            map.put(key, removeEmptyFields((ObjectNode)value));
            ret.setAll(map);
        }
        else if (value instanceof ArrayNode) {
            if (value.size() > 0){
                ret.set(key, removeEmptyFields((ArrayNode)value));
            }
        }
        else if (value.asText() != null && !value.asText().isEmpty()) {
            ret.set(key, value);
        }
    }

    return ret;
}


private static ArrayNode removeEmptyFields(ArrayNode array) {
    ArrayNode ret = new ObjectMapper().createArrayNode();
    Iterator<JsonNode> iter = array.elements();

    while (iter.hasNext()) {
        JsonNode value = iter.next();

        if (value instanceof ArrayNode) {
            ret.add(removeEmptyFields((ArrayNode)(value)));
        }
        else if (value instanceof ObjectNode) {
            ret.add(removeEmptyFields((ObjectNode)(value)));
        }
        else if (value != null && !value.textValue().isEmpty()){
            ret.add(value);
        }
    }

    return ret;
}
riorio
  • 6,500
  • 7
  • 47
  • 100