2013-05-17 78 views
3

請看下面的接口/對象分層結構中的彈簧項目:我可以控制如何實例化spring控制器方法參數嗎?

@RequestMapping(method = POST, value = "/posturi", consumes = "application/json") 
public void createEntity(@RequestBody MyClass myClass) { 
    //handle request 
} 

傑克遜庫用來:

public interface MyInterface { 
    //method defenitions 
} 

@Component 
@Scope(SCOPE_PROTOTYPE) 
public class MyClass implements MyInterface { 
    //method implementations 
} 

我在其被從所述請求體讀出的控制器的方法使用MyClass讀取json數據並將其轉換爲java對象。

我想將控制器方法中參數的類型從MyClass更改爲MyInterface。這似乎不起作用,因爲接口不能用new運算符實例化。但可能這樣創建:

MyInterface instance = applicationContext.getBean(MyInterface.class); 

是否有可能使春/傑克遜實例化對象這種方式?我想這樣做,以便我的控制器不需要知道使用了什麼實現。

回答

0

我已經解決了這個問題,這個概念很簡單,但實現起來可能有點棘手。據我所知,只要你提供一個HttpMessageConverter,你可以用@RequestBody註釋任何類型,它可以從一個http請求轉換爲你想要的類型。 因此,解決辦法是:

  1. ,使得在使用你的HttpMessageConverter實現一個HttpMessageConverter
  2. 配置Spring。

第二部分可能有點棘手。這是因爲spring添加了一堆默認的HttpMessageConverter,它可以處理常見的類型,比如字符串,整數,日期,我希望它們像往常一樣繼續工作。另一個問題是,如果jackson在路徑上,spring還會爲通用的json處理添加一個MappingJackson2HttpMessageConverter,例如轉換爲具體對象,地圖等。 Spring會使用第一個HttpMessageConverter它認爲聲稱能夠轉換爲您的類型。 MappingJackson2HttpMessageConverter聲稱能夠爲我的對象執行此操作,但無法執行,因此失敗並且請求失敗。這可以被認爲是一個錯誤......

,我想環比:

  1. 泉默認HttpMessageConverter秒。
  2. 我自己HttpMessageConverter
  3. MappingJackson2HttpMessageConverter

我發現了兩種方式來達致這。首先,你可以通過xml明確地聲明它。

<mvc:annotation-driven> 
    <mvc:message-converters> 
     <!-- All converters in specific order here --> 
    </mvc:message-converters> 
</mvc:annotation-driven> 

這樣做的缺點是,如果在以後的版本默認HttpMessageConverter鏈的變化,也不會爲您的配置更改。

另一種方法是以編程方式在MappingJackson2HttpMessageConverter之前插入您自己的HttpMessageConverter

@Configuration 
public class MyConfiguration { 

    @Autowired 
    private RequestMappingHandlerAdapter adapter; 

    @Autowired 
    private MyHttpMessageConverter myHttpMessageConverter; 

    @PostConstruct 
    private void modify() { 
     List<HttpMessageConverter<?>> messageConverters = adapter.getMessageConverters(); 
     int insertLocation = messageConverters.size() - 1; 
     for (int i = 0; i < messageConverters.size(); i++) { 
      Object messageConverter = messageConverters.get(i); 
      if (messageConverter instanceof MappingJackson2HttpMessageConverter) { 
       insertLocation = i; 
      } 
     } 
     messageConverters.add(insertLocation, myHttpMessageConverter); 
    } 
} 

即使在以後的版本中發生更改,第二個選擇將繼續使用「默認配置」。我認爲這有點冒險,根本沒有優雅,但我認爲這是一個有效的解釋的原因是,似乎有缺陷在MappingJackson2HttpMessageConverter聲稱能夠轉換爲它不能轉換的類型。此外,您無法明確地將HttpMessageConverter添加到鏈中的特定位置。

現在我有第二個選項將會而是你如何做的是給你......

0

它應該有可能與轉換器。請參閱文檔http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/validation.html。問題是,你怎麼知道你通過轉換器返回哪個類?而是重新考慮您的設計,以便在輸入中使用POJO。

+0

整點是不知道的情況下會是怎樣。只要它實現MyInterface,它就會好的。 –

+0

查看轉換器的文檔我沒有看到他們如何在不知道MyClass的情況下將MyInterface的實例注入到控制器方法中的可能性。 –

+0

應該是這樣的:'類StringToMyInterface實現轉換器<字符串,MyInterface的> { \t公共MyInterface的轉換(字符串源){ \t \t MyInterface的I =新MyClass的(); //實現MyIterface \t \t return i; \t} }'你總是必須返回類的實例 – igo

相關問題