so-random-dude
so-random-dude

Reputation: 16465

Jackson is ignoring spring.jackson.properties in my spring boot application

Jackson is ignoring spring.jackson.property-naming-strategy=SNAKE_CASE. I am using springBootVersion 1.4.2.RELEASE. In my application.properties file, I have added

spring.jackson.property-naming-strategy=SNAKE_CASE

But Jackson is not honoring this property, and my REST response is still camelCase. Interestingly, this annotation works just fine

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)

With this annotation, I am getting snake_case response. But I don't want to annotate each response class, it's a bit annoying.

Edit

I tried using fully qualified class name as well,

spring.jackson.property-naming-strategy=com.fasterxml.jackson.databind.PropertyNamingStrategy.SnakeCaseStrategy

that did not work either

Upvotes: 19

Views: 22924

Answers (7)

Nuno Nelas
Nuno Nelas

Reputation: 56

For anyone who stumbles on this thread, I had the same symptom as OP and for my case, it was happening because I'd defined a @Bean for a JsonMapper (to use on different parts of my code), like this:

  @Bean
  fun objectMapper(): JsonMapper {
    return JsonMapper.builder()
      .findAndAddModules()
      .build()
  }

The thing that I forgot is that Spring uses Jackson to convert messages. So, in order to fix it, I just had to define a PropertyNamingStrategies:

  @Bean
  fun objectMapper(): JsonMapper {
    return JsonMapper.builder()
      .findAndAddModules()
      .propertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)
      .build()
  }

Upvotes: -3

王晓风
王晓风

Reputation: 21

I think maybe you created class extends WebMvcConfigurationSupport ,WebMvcConfigurationSupport contains @EnableWebMvc, do not extends WebMvcConfigurationSupport ,do use some class extends WebMvcConfigurationSupport

Upvotes: 2

Chris Paika
Chris Paika

Reputation: 97

For the record, to solve a similar problem I added this to my application.properties and it worked well: spring.jackson.property-naming-strategy=SNAKE_CASE

Note, you don't need to fully qualify the SNAKE_CASE like in other answers

Upvotes: -1

Neo Pham
Neo Pham

Reputation: 372

Just like @skadya's answer, I update it in new spring version and Java 8 styles.

@EnableWebMvc
@Configuration
public class WebConfig implements WebMvcConfigurer {
    private ObjectMapper mapper;

    @Autowired  // spring.jackson.* ObjectMapper's config
    public WebConfig(ObjectMapper mapper) {
        this.mapper = mapper;
    }

    @Override
    public void extendMessageConverters (List<HttpMessageConverter<?>> converters) {
        converters.stream()
                .filter(x -> x instanceof  MappingJackson2HttpMessageConverter)
                .forEach(x -> ((MappingJackson2HttpMessageConverter) x).setObjectMapper(mapper));
    }
}

Upvotes: 1

so-random-dude
so-random-dude

Reputation: 16465

I had @EnableWebMvc annotation in one of the classes (ExceptionHandler) in my Application (face-palm!).

But, as per this issue,

If you have @EnableWebMvc annotation, that disables the auto-configuration of Spring MVC, including the configuring of its message converters to customize Jackson's serialization.

It's expected behavior when you use @EnableWebMvc as, by doing so, you're telling Spring Boot that you want to take control of Spring MVC's configuration. That includes configuring its HTTP message converters to (de)serialize JSON in the manner that meets your needs.

If you want to override the Jackson configuration, you can either use the spring.jackson.* properties or, if you want more control, declare your own Jackson2ObjectMapperBuilder bean.

Once I removed @EnableWebMvc annotation, this property works as expected.

Upvotes: 28

skadya
skadya

Reputation: 4390

MappingJackson2HttpMessageConverter class uses the default instance created by Jackson2ObjectMapperBuilder.json() method. In order to use application conext's ObjectMapper, you can register a custom WebMvcConfigurerAdapter.

@Configuration
public class WebMvcDefaultObjectMapperConfigurerAdapter extends WebMvcConfigurerAdapter {

    private ObjectMapper mapper;

    @Autowired
    public WebMvcDefaultObjectMapperConfigurerAdapter(ObjectMapper mapper) {
        // default mapper configured with spring.*
        this.mapper = mapper;
    }

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        for (HttpMessageConverter<?> httpConverter : converters) {
            if (httpConverter instanceof MappingJackson2HttpMessageConverter) {
                // register the configured object mapper to HttpMessageconter
                ((MappingJackson2HttpMessageConverter) httpConverter).setObjectMapper(mapper);
            }
        }
    }
}

Upvotes: 2

Liping Huang
Liping Huang

Reputation: 4476

According to the doc

/**
 * One of the constants on Jackson's PropertyNamingStrategy
 * (CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES). Can also be a fully-qualified class
 * name of a PropertyNamingStrategy subclass.
 */
private String propertyNamingStrategy;

You can config it in "application.properties" with this:

spring.jackson.property-naming-strategy=com.fasterxml.jackson.databind.PropertyNamingStrategy.SnakeCaseStrategy

Upvotes: 4

Related Questions