how to convert all the nested fields of the following object rendered as json to snake_case? Given it’s read as a org.bson.Document, jackson object mapper won’t work as it’s designed for POJOs and it’s not possible to have POJOs here as the records are schema-less
{
"project_data":[
{
"color":"#ffcd03",
"boardId":"30022"
},
{
"color":"#ffcd03",
"boardId":"1559427"
}
],
"type":"Standard",
"enterprise_id":"30000",
"version":"10",
"card_type_id":"30017",
"owner_type":"Org",
"timestamp":"1640901794509"
}
Advertisement
Answer
It can be easily done by adding a custom key serializer to SimpleModule, then register it to ObjectMapper as follows:
Create a class SnakeCaseSerializer which extends JsonSerializer to override serialize() to modify the key from lower camel case to lower underscore case (aka snake case) with Google Guava library – CaseFormat.
public class SnakeCaseSerializer extends JsonSerializer<String> {
@Override
public void serialize(String s, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
String fieldNameNew = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, s);
jsonGenerator.writeFieldName(fieldNameNew);
}
}
Add this class into SimpleModule as custom key serializer, then register the module to your ObjectMapper. (This way is going to change ALL the field names, but it doesn’t matter because the field names belong to first level are already in snake case.)
SimpleModule simpleModule = new SimpleModule();
simpleModule.addKeySerializer(String.class, new SnakeCaseSerializer());
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(simpleModule);
System.out.println(objectMapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(objectMapper.readValue(jsonStr, Object.class)));
Console output:
{
"project_data" : [ {
"color" : "#ffcd03",
"board_id" : "30022"
}, {
"color" : "#ffcd03",
"board_id" : "1559427"
} ],
"type" : "Standard",
"enterprise_id" : "30000",
"version" : "10",
"card_type_id" : "30017",
"owner_type" : "Org",
"timestamp" : "1640901794509"
}