Jackson overcoming underscores in favor of camel-case

JavaJackson

Java Problem Overview


I retrieve a JSON string from internet; like most JSON I've seen it includes long keys that are separated by underscores. Essentially, my goal is to deserialize JSON into java-objects, but I don't use underscores in java-code.

For instance, I might have a User class with firstName field in camel-case, simultaneously I need somehow to tell Jackson to map first_name key from JSON to firstName class field. Is it possible?

class User{
    protected String firstName;
    protected String getFirstName(){return firstName;}
}

Java Solutions


Solution 1 - Java

You can configure the ObjectMapper to convert camel case to names with an underscore:

objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);

Or annotate a specific model class with this annotation:

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)

Before Jackson 2.7, the constant was named:

PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES


   

Solution 2 - Java

If its a spring boot application, In application.properties file, just use

> spring.jackson.property-naming-strategy=SNAKE_CASE

Or Annotate the model class with this annotation.

> @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)

Solution 3 - Java

You should use the @JsonProperty on the field you want to change the default name mapping.

class User{
    @JsonProperty("first_name")
    protected String firstName;
    protected String getFirstName(){return firstName;}
}

For more info: the API

Solution 4 - Java

If you want this for a Single Class, you can use the PropertyNamingStrategy with the @JsonNaming, something like this:

@JsonNaming(PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy.class)
public static class Request {

	String businessName;
	String businessLegalName;

}

Will serialize to:

{
    "business_name" : "",
    "business_legal_name" : ""
}

Since Jackson 2.7 the LowerCaseWithUnderscoresStrategy in deprecated in favor of SnakeCaseStrategy, so you should use:

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public static class Request {

	String businessName;
	String businessLegalName;

}

Solution 5 - Java

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:

@Bean
public ObjectMapper jacksonObjectMapper() {
    return new ObjectMapper().setPropertyNamingStrategy(
            PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
}

Solution 6 - Java

The current best practice is to configure Jackson within the application.yml (or properties) file.

Example:

spring:
  jackson:
    property-naming-strategy: SNAKE_CASE

If you have more complex configuration requirements, you can also configure Jackson programmatically.

import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

@Configuration
public class JacksonConfiguration {

    @Bean
    public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() {
        return new Jackson2ObjectMapperBuilder()
                .propertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        // insert other configurations
    }

} 

Solution 7 - Java

In order to annotate the model class use:

@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)

Instead of:

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)

It was deprecated since 2.12.

Solution 8 - Java

There are few answers here indicating both strategies for 2 different versions of Jackson library below:

For Jackson 2.6.*

ObjectMapper objMapper = new ObjectMapper(new JsonFactory()); // or YAMLFactory()
objMapper.setNamingStrategy(
     PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);

For Jackson 2.7.*

ObjectMapper objMapper = new ObjectMapper(new JsonFactory()); // or YAMLFactory()
objMapper.setNamingStrategy(
     PropertyNamingStrategy.SNAKE_CASE);

Solution 9 - Java

Annotating all model classes looks to me as an overkill and Kenny's answer didn't work for me https://stackoverflow.com/a/43271115/4437153. The result of serialization was still camel case.

I realised that there is a problem with my spring configuration, so I had to tackle that problem from another side. Hopefully someone finds it useful, but if I'm doing something against springs' rules then please let me know.

Solution for Spring MVC 5.2.5 and Jackson 2.11.2

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);           

        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setObjectMapper(objectMapper);
        converters.add(converter);
    }
}

Solution 10 - Java

  1. You can use the @JsonProperty annotation on the fields of our class to map the fields to the exact names in our JSON

    > @JsonProperty("my_name") > private String myName;

  2. You can use @JsonNaming annotation on the class, and all fields will be deserialized using snake case

    > @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) > public class MyClassWithSnakeStrategy { ...

}

  1. You can use the setPropertyNamingStrategy method on ObjectMapper to configure it for all serialization

    > ObjectMapper objectMapper = new ObjectMapper()
    > .setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1384991View Question on Stackoverflow
Solution 1 - JavathehpiView Answer on Stackoverflow
Solution 2 - Javaadam.smithsonian01View Answer on Stackoverflow
Solution 3 - JavaAlexView Answer on Stackoverflow
Solution 4 - JavaArturo VolpeView Answer on Stackoverflow
Solution 5 - JavaDawngerponyView Answer on Stackoverflow
Solution 6 - JavaKenny CasonView Answer on Stackoverflow
Solution 7 - JavaandreytView Answer on Stackoverflow
Solution 8 - JavaAmit KaneriaView Answer on Stackoverflow
Solution 9 - JavarudaldView Answer on Stackoverflow
Solution 10 - JavaForgeryView Answer on Stackoverflow