2013-09-29 40 views
1

我在尋找有關處理以下情況的最佳做法的建議。JSON到Java映射參數化/泛型類型

鑑於接受JSON請求的基於Java的Web API,我們需要將JSON對象映射到Java。這個問題是關於Java對象是參數類型的情況。對於我的特殊情況,我使用Spring和MappingJacksonHttpMessageConverter進行映射。

例REST服務

@RequestMapping(method = RequestMethod.POST) 
public void updateContainer(@RequestBody Container<?> container) { 
    realService.updateContainer(container); 
} 

實施例參數型

public class Container<T extends ContainerItem> { 
     private T containerItem; 
     ... 
} 

當我把這種方法,因爲容器的類型是在運行時和Jackson擦除我將得到一個400錯誤(不良請求)不知道如何映射我的containerItem(因爲它不知道映射到什麼類型)。

我實現了一個非常基本的解決方案,我在其中一個字段添加到指定containerItem的Java類名的JSON數據,然後添加自定義HttpMessageConverter使用這個類名來構建一個參數的javaType其中傑克遜ObjectMapper能然後用來做映射,但我想知道是否有人有更好的方式來處理這個問題?

+1

我會避免暴露在JSON中沒有任何等同物的構造(比如泛型,集合等)。這使得很難弄清楚服務是如何被使用的。 – millimoose

+0

你好毫米,這是一個公平的點,但我想我希望這將是一個普遍的問題,可能有一些傑克遜的最佳實踐模式或語言功能來幫助處理它。作爲一個例子,JSON沒有多態類型的等價物,然而Jackson能夠通過註釋來處理這些類型。 – Josh

回答

4

的溶液。將聲明一個參數類型,並使用此作爲@RequestBody目標是這樣的:

public class MyCustomTypeContainer extends Container<SubContainerItem> { 
.. 
} 

public void updateContainer(@RequestBody MyCustomTypeContainer container) { 
    realService.updateContainer(container); 
} 

筆記,該MyCustomTypeContainer必須是一個參數類型(通用類型的完全實現)。這可能意味着您可能必須爲每個containerItem類型創建一個子類型。

請參閱here瞭解另一個問題。

+0

嗨Biju,這種解決方案將工作,如果我只想updateContainer與一個具體類型的子容器(SubContainerItem) - 但如果我也想要能夠更新容器充滿SubContainerItem2? – Josh

+0

是真正的喬希,實際上你的方法聽起來也不錯。我能想到的一個變化是沒有xml中的類名,看起來並不乾淨,而是嘗試將這些信息放在自定義註釋中,並使用該註釋和[HandlerMethodArgumentResolver](http:// docs。 spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/web/method/support/HandlerMethodArgumentResolver.html)來創建適當的'JavaType'並在那裏進行解組。 –