2015-10-19 114 views
3

我正在使用@Bean註釋定義bean,並嘗試使用名稱連接它們,但接收到異常。無法在Spring Boot應用程序中注入多個ObjectMapper bean

完整的例子

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

控制器

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


} 

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

異常

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 
+0

對不起尼爾,這是一個錯字,當我輸入在這裏。我在我的代碼中使用了正確的限定符。 –

+0

我無法複製此內容。請發佈完整的示例。 –

+0

@SotiriosDelimanolis,發佈完整的例子。該服務器甚至沒有啓動,我點擊運行後彈出應用程序,我得到一個錯誤。 –

回答

8

默認情況下,Spring Boot定義了一個類型爲MappingJackson2HttpMessageConverter的bean並嘗試向其中注入ObjectMapper。這通常可以讓你簡單地聲明一個ObjectMapper@Bean,以任何你需要的方式進行配置,並讓Spring Boot爲你做其餘的事情。

在這裏,因爲你聲明瞭其中的兩個,所以這已經不起作用。

一個解決方案,as described in the documentation,是註釋@Bean的定義,你想注入的爲@Primary

如果要替換默認ObjectMapper完全定義類型的 @Bean並將其標記爲@Primary

例如,

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

春季啓動將使用那一個。

或者,您可以聲明自己的MappingJackson2HttpMessageConverter bean定義並在內部配置所有內容。從同一個文檔

最後,如果你提供任何@Bean S型 MappingJackson2HttpMessageConverter的那麼他們將取代MVC配置默認 值。

例如(從here拍攝)

@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; 
} 
+0

非常感謝您的詳細解釋。這幫了我很多,解決了我的問題:-) –

相關問題