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"
}