I'm dealing with JSON whose property names are snake-cased, but, I need these transformed into a lower camel case.
I don't have beans for all the corresponding objects so the usual ser-de tricks of Jackson don't apply (I think).
I tried reading it into a Map
and setting a global property naming strategy but that didn't work.
String json = "{\"first_name\": \"John\", \"last_name\": \"Doe\" }";
Map<?, ?> myMap = new ObjectMapper().readValue(json, Map.class);
System.out.println(new ObjectMapper()
.setPropertyNamingStrategy(new UpperCamelCaseStrategy())
.writerWithDefaultPrettyPrinter()
.writeValueAsString(myMap));
I don't need this to be necessarily accomplished in Jackson. While a simple problem, it did leave me quite lost as to what a sane way of accomplishing this might be.
CodePudding user response:
I found this solution, which is a bit hard-coded, using regex. In this way, however, you do not need to use any JsonObject
library.
I wrote three methods:
one to convert a string from snake_case to pascalCase
private static String convertToPascalCase(String str){ while(str.contains("_")) { str = str.replaceFirst("_[a-z]", String.valueOf(Character.toUpperCase(str.charAt(str.indexOf("_") 1)))); } return str; }
Another which handles the replacing of the regex matches
private static String replaceMatches(Matcher m, Function<MatchResult, String> mapping) { StringBuffer sb = new StringBuffer(); while (m.find()) { MatchResult matchResult = m.toMatchResult(); m.appendReplacement(sb, mapping.apply(matchResult)); } m.appendTail(sb); return sb.toString(); }
the last one which defines the appropriate regex and then calls
replaceMatches
public static String convertToPascalCaseAllJsonKeys(String jsonString) { Pattern p = Pattern.compile("\"(\\w )\":"); Matcher m = p.matcher(jsonString); return replaceMatches(m, mr -> "\"" convertToPascalCase(mr.group(1)) "\":"); }
The usage is the following:
String json = "{\"first_name\": \"John\", \"last_name\": \"Doe\", \"children\": [\"Jane\", \"Mary\", \"Harry\"]}";
String jsonWithPascalKey = convertToPascalCaseAllJsonKeys(json);
System.out.println(jsonWithPascalKey );
// result: {"firstName": "John", "lastName": "Doe", "children": ["Jane", "Mary", "Harry"]}
Then, you can easily convert the string to a JsonObject.
CodePudding user response:
https://github.com/octomix/josson
If the JSON has one level.
Josson josson = Josson.fromJsonString("{\"first_name\": \"John\", \"last_name\": \"Doe\"}");
JsonNode node = josson.getNode("entries().map(key.camelCase()::value).mergeObjects()");
System.out.println(node.toPrettyString());
Output
{
"firstName" : "John",
"lastName" : "Doe"
}
Nest the transformation query one more time for each additional level.
Josson josson = Josson.fromJsonString("{\"sales_person\":{\"first_name\": \"John\", \"last_name\": \"Doe\"}}");
JsonNode node = josson.getNode(
"entries()"
".map(key.camelCase()"
" ::value.entries()"
" .map(key.camelCase()"
" ::value)"
" .mergeObjects())"
".mergeObjects()");
System.out.println(node.toPrettyString());
Output
{
"salesPerson" : {
"firstName" : "John",
"lastName" : "Doe"
}
}