Spring启动没有使用配置的Jackson ObjectMapper和@EnableWebMvc

时间:2017-08-17 11:39:11

标签: spring-mvc spring-boot jackson

我想在我的项目中使用配置版本的jackson对象映射器(忽略空值和snake_case,还有一些自定义模块)。

在我的大型项目中,我无法获得spring mvc来实际使用此映射器。

build.gradle:

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

我的application.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一起使用,而不是删除WebMvc的其余自动配置?

1 个答案:

答案 0 :(得分:2)

仅从Javadocs上并不能看出来,但是@EnableWebMvc禁用了WebMvcAutoConfiguration提供的Spring Boot默认Web MVC自动配置,包括使用{所配置的Jackson ObjectMapper bean {1}}个属性。根据{{​​3}}:

9.4.7。关闭默认的MVC配置

完全控制MVC配置的最简单方法是为自己的application.yml提供@Configuration批注。这样做会使您掌握所有MVC配置。

要使用带有@EnableWebMvc属性的@EnableWebMvc批注,您需要手动配置MVC配置以使用自动装配的application.yml bean。可以使用自定义ObjectMapper完成此操作。有几种不同的解决方法。

第一种选择是复制Spring Boot Reference Documentation中的代码。这将使用默认Spring Boot配置所使用的消息转换器替换消息转换器-包括包含WebMvcConfigurer bean的WebMvcAutoConfiguration.EnableWebMvcConfiguration.configureMessageConverters()

ObjectMapper

或者,如果您不想使用消息转换器的默认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())); } } ObjectMapper bean:

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

    }
}