[java] Jackson overcoming underscores in favor of camel-case

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

This question is related to java jackson

The answer is


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);
}

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;

}

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)


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);
    }
}

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
    }

} 

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

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);