无法在Spring Boot应用程序中注入多个ObjectMapper bean

Pun*_*cky 6 jackson spring-boot

我使用@Bean注释定义bean并尝试使用name连接它们,但是接收异常.

完整的例子

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import com.fasterxml.jackson.databind.ObjectMapper;

@SpringBootApplication
@ComponentScan({"com.example"})
public class SampleSpringBootApplication {

    public static void main(String[] args) {
        SpringApplication.run(SampleSpringBootApplication.class, args);
    }


    @Bean
    public ObjectMapper scmsObjectMapper() {
        com.fasterxml.jackson.databind.ObjectMapper responseMapper = new com.fasterxml.jackson.databind.ObjectMapper();
        return responseMapper;
    }

    @Bean
    public ObjectMapper scmsWriteObjectMapper() {
        com.fasterxml.jackson.databind.ObjectMapper responseMapper = new com.fasterxml.jackson.databind.ObjectMapper();
        return responseMapper;
    }
}
Run Code Online (Sandbox Code Playgroud)

调节器

package com.example;

import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SampleController {

    @RequestMapping(method={RequestMethod.GET}, value="sample/hello", produces=MediaType.APPLICATION_JSON_VALUE)
    @ResponseStatus(HttpStatus.OK)
    public @ResponseBody ResponseEntity<String> getCart() {
        return new ResponseEntity<String>("Hello", HttpStatus.OK);
    }


}
Run Code Online (Sandbox Code Playgroud)

的build.gradle

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

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot' 
apply plugin: 'io.spring.dependency-management' 

jar {
    baseName = 'Sample-SpringBoot'
    version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    mavenCentral()
}


dependencies {
    compile('org.springframework.boot:spring-boot-starter')
    testCompile('org.springframework.boot:spring-boot-starter-test') 
    compile("org.springframework.boot:spring-boot-starter-web:1.2.3.RELEASE")
    compile('com.fasterxml.jackson.core:jackson-databind:2.5.1')
}


eclipse {
    classpath {
         containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
         containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8'
    }
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.7'
}
Run Code Online (Sandbox Code Playgroud)

例外

 Caused by:
 org.springframework.beans.factory.NoUniqueBeanDefinitionException: No
 qualifying bean of type [com.fasterxml.jackson.databind.ObjectMapper]
 is defined: expected single matching bean but found 2:
 scmsObjectMapper,scmsWriteObjectMapper
Run Code Online (Sandbox Code Playgroud)

Sot*_*lis 18

默认情况下,Spring Boot定义了一个类型的bean MappingJackson2HttpMessageConverter并尝试将其ObjectMapper注入其中.这通常允许您简单地声明一个ObjectMapper @Bean,以任何方式配置它,并让Spring Boot为您完成剩下的工作.

在这里,这已经适得其反,因为你声明了其中两个.

如文档中所述,一种解决方案是注释@Bean您想要注入的定义@Primary.

如果要ObjectMapper完全替换默认值,请定义 @Bean该类型并将其标记为@Primary.

例如,

@Bean
@Primary
public ObjectMapper scmsObjectMapper() {
    com.fasterxml.jackson.databind.ObjectMapper responseMapper = new com.fasterxml.jackson.databind.ObjectMapper();
    return responseMapper;
}
Run Code Online (Sandbox Code Playgroud)

Spring Boot将使用那个.

或者,您可以声明自己的MappingJackson2HttpMessageConverterbean定义并在内部配置所有内容.来自相同的文档

最后,如果您提供任何@Bean类型的类型, MappingJackson2HttpMessageConverter那么它们将替换MVC配置中的默认值.

例如(取自这里)

@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
    MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    jsonConverter.setObjectMapper(objectMapper);
    return jsonConverter;
}
Run Code Online (Sandbox Code Playgroud)