Spring启动未使用已配置的Jackson ObjectMapper和@EnableWebMvc

wvyml7n5  于 2022-11-08  发布在  Spring
关注(0)|答案(1)|浏览(217)

我想在我的项目中使用JacksonObjectMapper的配置版本(忽略空值和snake_case,还使用一些自定义模块)。
在我的大型项目中,我无法让SpringMVC实际使用这个Map器。
建筑等级:

buildscript {
  ext {
    springBootVersion = '1.5.6.RELEASE'
  }
  repositories {
    mavenCentral()
  }
  dependencies {
    classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
  }
}

apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'

version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
  mavenCentral()
}

dependencies {
  compile('org.springframework.boot:spring-boot-starter')
  compile("org.springframework.boot:spring-boot-starter-jetty:${springBootVersion}")
  compile("org.springframework.boot:spring-boot-starter-web:${springBootVersion}")

  compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.8.8'
  compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.8.8'

  testCompile('org.springframework.boot:spring-boot-starter-test')
}

我的应用程序.yml:

spring:
  application:
  name: Jackson test
jackson:
  property-naming-strategy: SNAKE_CASE
  default-property-inclusion: non_empty
debug: true

容器类:

public class MyLocationEntity {
    public String nameAndSnake;
}

配置类:

@Configuration
@EnableWebMvc
public class AppConfig {
}

和控制器:

@RestController
@RequestMapping("/test")
public class TestController {

  @Autowired
  private ObjectMapper objectMapper;

  @RequestMapping(value = "/test", produces = "application/json")
  public MyLocationEntity test() throws JsonProcessingException {
    MyLocationEntity location = new MyLocationEntity();
    location.nameAndSnake = "hello world";
    String expexted = objectMapper.writeValueAsString(location);
    return location;
  }
}

如果我现在在调试器中查看expected的值,它是{"name_and_snake":"hello world"}。但是如果我让控制器运行,实际响应是{"nameAndSnake":"hello world"}
当我删除@EnableWebMvc时,它工作了。我如何使用MVC配置的Map器,而不删除Web MVC的其他自动配置?

mkshixfv

mkshixfv1#

仅从Javadoc中看不出来,但是@EnableWebMvc禁用了由WebMvcAutoConfiguration提供的Sping Boot 默认Web MVC自动配置,包括使用application.yml属性配置的JacksonObjectMapper bean。

9.4.7.关闭默认MVC配置

完全控制MVC配置的最简单方法是提供您自己的@Configuration@EnableWebMvc注解。这样做可以将所有的MVC配置都交给您。
由于@EnableWebMvc具有禁用自动配置的行为(可能令人惊讶),因此使用此注解可能会产生意外的不良副作用。使用不同的方法可能更合适。
这就是说,@EnableWebMvc的行为可能仍然是需要的。要将application.yml属性与@EnableWebMvc注解一起使用,必须手动配置MVC配置,以模拟相关的禁用Sping Boot 自动配置。有几种不同的可能方法来实现这一点。
第一种方法是从WebMvcAutoConfiguration.EnableWebMvcConfiguration.configureMessageConverters()复制Sping Boot 配置代码。这将替换消息转换器(包括包含未配置ObjectMapperMappingJackson2HttpMessageConverter),使用默认Spring Boot配置所使用的消息转换器:

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private ObjectProvider<HttpMessageConverters> messageConvertersProvider;

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        this.messageConvertersProvider
                .ifAvailable((customConverters) -> converters.addAll(customConverters.getConverters()));
    }
}

或者,也可以不使用缺省的Sping Boot 消息转换器列表,而只换入Spring Boot提供的ObjectMapperMappingJackson2HttpMessageConverter bean(它们应用了application.yml属性):

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.stream()
                .filter(c -> c instanceof MappingJackson2HttpMessageConverter)
                .map(c -> (MappingJackson2HttpMessageConverter) c)
                .forEach(c -> c.setObjectMapper(objectMapper));

    }
}

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter;

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        for (int i = 0; i < converters.size(); i++) {
            if (converters.get(i) instanceof MappingJackson2HttpMessageConverter) {
                converters.set(i, mappingJackson2HttpMessageConverter);
            }
        }
    }
}

相关问题