Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson json to map and camelcase key name

Tags:

java

json

jackson

I want to convert json via jackson library to a map containing camelCase key...say...

from

{
    "SomeKey": "SomeValue",
    "AnotherKey": "another value",
    "InnerJson" : {"TheKey" : "TheValue"}
}

to this...

{
    "someKey": "SomeValue",
    "anotherKey": "another value",
    "innerJson" : {"theKey" : "TheValue"}
}

My Code...

public Map<String, Object> jsonToMap(String jsonString) throws IOException
{
    ObjectMapper mapper=new ObjectMapper();
    mapper.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
    return mapper.readValue(jsonString,new TypeReference<Map<String, Object>>(){});
}

But this doesn't work...even other propertyNamingStrategy does not work on json...such as...

{
    "someKey": "SomeValue"
}

mapper.setPropertyNamingStrategy(new PropertyNamingStrategy.PascalCaseStrategy())

to

{
    "SomeKey": "SomeValue"
}

How to get the camelCase Map key name via jackson... or should I manually loop map and convert key or there are some other way???

Thanks in advance...

like image 948
Shakil Avatar asked Jun 09 '15 08:06

Shakil


People also ask

How to serialize a map<string> to JSON in Jackson?

For a simple case, let's create a Map<String, String> and serialize it to JSON: Map<String, String> map = new HashMap<> (); map.put ( "key", "value" ); ObjectMapper mapper = new ObjectMapper (); String jsonResult = mapper.writerWithDefaultPrettyPrinter () .writeValueAsString (map); ObjectMapper is Jackson's serialization mapper.

What is camel case JSON property names online converter tool?

Camel Case Json Property Names Online Converter Tool converts all Json Property Names from Snake Case or Pascal Case to Camel Case style. linkPascal Case Json Property Names linkSnake Case Json Property Names linkTitle Case Converter

How accurate are @jsonproperty and camel_case_to_lower_case_with_underscores?

The above answers regarding @JsonProperty and CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES are 100% accurate, although some people (like me) might be trying to do this inside a Spring MVC application with code-based configuration. Here's sample code (that I have inside Beans.java) to achieve the desired effect:

How to convert camel case to names in objectmapper?

You can configure the ObjectMapper to convert camel case to names with an underscore: Show activity on this post. If its a spring boot application, In application.properties file, just use Or Annotate the model class with this annotation. Show activity on this post.


2 Answers

As you are working with maps/dictionaries instead of binding the JSON data to POJOs (explicit Java classes that match the JSON data), the property naming strategy does not apply:

Class PropertyNamingStrategy ... defines how names of JSON properties ("external names") are derived from names of POJO methods and fields ("internal names")

Therefore, you have to first parse the data using Jackson and then iterate over the result and convert the keys.

Change your code like this:

public Map<String, Object> jsonToMap(String jsonString) throws IOException
{
    ObjectMapper mapper=new ObjectMapper();
    mapper.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
    Map<String, Object> map = mapper.readValue(jsonString,new TypeReference<Map<String, Object>>(){});
    return convertMap(map);
}

And add these methods:

public String mapKey(String key) {
    return Character.toLowerCase(key.charAt(0)) + key.substring(1);
}

public Map<String, Object> convertMap(Map<String, Object> map) {
    Map<String, Object> result = new HashMap<String, Object>();
    for (Map.Entry<String, Object> entry : map.entrySet()) {
        String key = entry.getKey();
        Object value = entry.getValue();
        result.put(mapKey(key), convertValue(value));
    }
    return result;
}

public convertList(Lst<Object> list) {
    List<Object> result = new ArrayList<Object>();
    for (Object obj : list) {
        result.add(convertValue(obj));
    }
    return result;
}

public Object covertValue(Object obj) {
    if (obj instanceof Map<String, Object>) {
        return convertMap((Map<String, Object>) obj);
    } else if (obj instanceof List<Object>) {
        return convertList((List<Object>) obj);
    } else {
        return obj;
    }
}
like image 107
Codo Avatar answered Oct 29 '22 13:10

Codo


You always can iterate over the keys of the map and update them. However, if you are only interested in producing a JSON with camel case keys, you could consider the approach described below.

You could have a custom key serializer. It will be used when serializing a Map instance to JSON:

public class CamelCaseKeySerializer extends JsonSerializer<String> {

    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers)
                throws IOException, JsonProcessingException {

        String key = Character.toLowerCase(value.charAt(0)) + value.substring(1);
        gen.writeFieldName(key);
    }
}

Then do as following:

String json = "{\"SomeKey\":\"SomeValue\",\"AnotherKey\":\"another value\",\"InnerJson\":"
            + "{\"TheKey\":\"TheValue\"}}";

SimpleModule simpleModule = new SimpleModule();
simpleModule.addKeySerializer(String.class, new CamelCaseKeySerializer());

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(simpleModule);

Map<String, Object> map = mapper.readValue(json, 
                                          new TypeReference<Map<String, Object>>() {});

String camelCaseJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(map);

The output will be:

{
  "someKey" : "SomeValue",
  "anotherKey" : "another value",
  "innerJson" : {
    "theKey" : "TheValue"
  }
}

With this approach, the keys of the Map won't be in camel case. But it will give you the desired output.

like image 43
cassiomolin Avatar answered Oct 29 '22 13:10

cassiomolin