2012-11-27 16 views
24

我使用Jersey/Java創建了一個REST服務器,我發現了一個奇怪的行爲。Jersey:具有1個元素的Json數組被序列化爲對象

我有一個返回對象的數組爲JSON

@GET 
@Path("/files") 
@Produces(MediaType.APPLICATION_JSON) 
public Object getFiles() throws Exception{ 
    DatabaseManager db = new DatabaseManager(); 
    FileInfo[] result = db.getFiles(); 
    return result; 
} 

的代碼被正確地執行,並且數據被返回給客戶端(一個jQuery AJAX調用)在服務器上的方法。 問題是,如果「結果」數組有一個元素或多個元素,則返回數據的格式會發生變化。

一個元素響應:

{"fileInfo":[{"fileName":"weather.arff","id":"10"},{"fileName":"supermarket.arff","id":"11"}]} 

正如你所看到的,在第一種情況中返回的對象「的fileInfo」屬性的值是:

{"fileInfo":{"fileName":"weather.arff","id":"10"}} 

有兩個元素響應一個對象,在第二種情況下,該值是一個數組。 我在做什麼錯?不應該第一個案例返回這樣的事情:

{"fileInfo":[{"fileName":"weather.arff","id":"10"}]} 

即一個數組與單個對象裏面?

我知道我可以在客戶端檢測到這一點,但它看起來像一個非常醜陋的黑客。

謝謝你的時間。

回答

0

您可以使用Jettison(與Jersey一起提供)並準備您希望使用JSONObjectJSONArray作爲返回值的結構。 他們是在包的jettison-1.3.2.jarorg.codehaus.jettison.json這是如果你使用JAXB構建JSON結果jerysey-json

+0

JSONArray類的定義在哪裏?我必須從json.org添加json庫嗎? – willvv

5

傳遞依賴,則可以配置澤西JSON。處理器得到更重要的JSON格式。

jersey official document有詳細配置:

爲了達到更重要的JSON格式的變化,你需要配置澤西JSON。處理器本身。可以在JSONConfiguration實例上設置各種配置選項。然後該實例可以進一步用於創建JSONConfigurated JSONJAXBContext,該JSONJAXBContext用作此區域中的主要配置點。要通過你的專業JSONJAXBContext澤西島,你將最終需要實現的JAXBContext ContextResolver:

@Provider 
public class JAXBContextResolver implements ContextResolver<JAXBContext> { 
    private final JAXBContext context; 
    private final Set<Class> types; 
    private Class[] ctypes = { FileInfo.class}; //your pojo class 
    public JAXBContextResolver() throws Exception { 
     this.types = new HashSet(Arrays.asList(ctypes)); 
     this.context = new JSONJAXBContext(JSONConfiguration.natural().build(), 
       ctypes); //json configuration 
    } 

    @Override 
    public JAXBContext getContext(Class<?> objectType) { 
     return (types.contains(objectType)) ? context : null; 
    } 
} 
0

您也可以嘗試Genson庫http://code.google.com/p/genson/。它與澤西島很好地融合在一起,只需將jar放入你的classpath中,一切都可以工作。它不需要你編寫額外的代碼,它應該像現在一樣工作,但沒有任何奇怪的結果。

11

我結束了使用傑克遜,也在官方澤西文檔(http://jersey.java.net/nonav/documentation/latest/user-guide.html#json.pojo.approach.section)中描述。

我曾嘗試過,但它沒有工作,因爲我沒有傑克遜jar在我的項目的構建路徑(基於文件,我認爲它是內置於球衣的核心庫)。

我剛添加的傑克遜all.jar在文件(http://wiki.fasterxml.com/JacksonDownload),並在配置

<init-param> 
      <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name> 
      <param-value>true</param-value> 
    </init-param> 

,瞧啓用POJO支持!

+0

這回答了我的問題,但未修改任何代碼。謝謝。 – Solostaran14

+0

謝謝,它也適用於我! :d – suuuzi

0
I'm using cxf, here is my applicationContext.xml to force array in JSON, 
<jaxrs:server id="myService" serviceName="MyService" 
address="/mysvc"> 
<jaxrs:serviceBeans> 
    <ref bean="myServiceImpl"/> 
</jaxrs:serviceBeans> 
<jaxrs:providers> 
    <bean class="org.apache.cxf.jaxrs.provider.json.JSONProvider"> 
    <property name="dropRootElement" value="true" /> 
    <property name="supportUnwrapped" value="true" /> 
    <property name="namespaceMap"> 
     <map> 
     <entry key="http://example.com/myservice" value=""/> 
     </map> 
    </property> 
    <property name="arrayKeys"> 
     <list> 
    <value>fileInfo</value> 
     </list> 
    </property>       
    </bean> 
</jaxrs:providers> 
</jaxrs:server> 
0

我很掙扎了一下,發現這個簡單的解決方案

在你的POM .xml:

<dependency> 
    <groupId>org.codehaus.jackson</groupId> 
    <artifactId>jackson-jaxrs</artifactId> 
    <version>1.9.13</version> 
</dependency> 
<dependency> 
    <groupId>org.codehaus.jackson</groupId> 
    <artifactId>jackson-xc</artifactId> 
    <version>1.9.13</version> 
</dependency> 

在你的web.xml中:

<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> 
<init-param> 
    <param-name>com.sun.jersey.config.property.packages</param-name> 
    <param-value>com.other-packages;org.codehaus.jackson.jaxrs</param-value> 
</init-param> 
相關問題