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