Jersey: Json array with 1 element is serialized as

2020-03-01 04:15发布

I'm creating a REST server with Jersey/Java and I found a strange behavior.

I have a method on the server that returns an array of objects as Json

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

The code is executed correctly and data is returned to the client (a jQuery ajax call). The problem is that the format of the returned data changes if the "result" array has one element or more than one.

Response with one element:

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

Response with two elements:

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

As you can see, in the first scenario the value of the "fileInfo" property of the returned object is an object, and in the second case the value is an array. What am I doing wrong? Shouldn't the first case return something like this:

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

i.e. an array with a single object inside?

I know that I can detect this on the client side, but it seems like a very ugly hack.

Thanks for your time.

8条回答
家丑人穷心不美
2楼-- · 2020-03-01 04:49

I ended up using Jackson, also described in the official Jersey documentation (http://jersey.java.net/nonav/documentation/latest/user-guide.html#json.pojo.approach.section).

I had tried that before but it wasn't working because I didn't have the jackson jar in the buildpath of my project (Based on the documentation I thought it was built into jersey's core library).

I just added the jackson-all.jar file (http://wiki.fasterxml.com/JacksonDownload) and enabled the POJO support in the configuration

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

And voilá!

查看更多
\"骚年 ilove
3楼-- · 2020-03-01 04:58

I've struggled quite a bit and found this simple solution

In your 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>

In your 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>
查看更多
再贱就再见
4楼-- · 2020-03-01 05:01

You could also try Genson library http://code.google.com/p/genson/. It integrates well with jersey, just drop the jar in your classpath and everything will work. It doesnt require you to write additional code, it should work like what you have now but without any weird result.

查看更多
forever°为你锁心
5楼-- · 2020-03-01 05:03

Also have a look at the following answer, that solved it for me:

How can I customize serialization of a list of JAXB objects to JSON?

查看更多
乱世女痞
6楼-- · 2020-03-01 05:03

You could use Jettison (coming with Jersey) and prepare the structure you would like to have yourself using JSONObject and JSONArray as return values. They are in the package org.codehaus.jettison.json of jettison-1.3.2.jar which is a transitive dependency of jerysey-json

查看更多
狗以群分
7楼-- · 2020-03-01 05:05

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>
查看更多
登录 后发表回答