java Jersey:具有 1 个元素的 Json 数组被序列化为对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13575280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Jersey: Json array with 1 element is serialized as object
提问by willvv
I'm creating a REST server with Jersey/Java and I found a strange behavior.
我正在用 Jersey/Java 创建一个 REST 服务器,我发现了一个奇怪的行为。
I have a method on the server that returns an array of objects as Json
我在服务器上有一个方法可以将对象数组作为 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.
代码正确执行,数据返回给客户端(jQuery ajax 调用)。问题是如果“结果”数组有一个或多个元素,则返回数据的格式会发生变化。
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”属性的值是一个对象,而在第二种情况下,该值是一个数组。我究竟做错了什么?不应该第一个案例返回这样的东西:
{"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.
谢谢你的时间。
回答by willvv
I ended up using Hymanson, also described in the official Jersey documentation (http://jersey.java.net/nonav/documentation/latest/user-guide.html#json.pojo.approach.section).
我最终使用了 Hymanson,在 Jersey 官方文档 (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 Hymanson jar in the buildpath of my project (Based on the documentation I thought it was built into jersey's core library).
我之前尝试过,但它不起作用,因为我的项目的构建路径中没有 Hymanson jar(根据文档,我认为它已内置到 jersey 的核心库中)。
I just added the Hymanson-all.jar file (http://wiki.fasterxml.com/HymansonDownload) and enabled the POJO support in the configuration
我刚刚添加了 Hymanson-all.jar 文件(http://wiki.fasterxml.com/HymansonDownload)并在配置中启用了 POJO 支持
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
And voilá!
瞧!
回答by secondflying
If you were using JAXB to build JSON result, you can configure Jersey JSON procesor to get more important JSON format.
如果您使用 JAXB 来构建 JSON 结果,您可以配置 Jersey JSON 处理器以获得更重要的 JSON 格式。
jersey official documenthas detailed config:
球衣官方文档有详细配置:
To achieve more important JSON format changes, you will need to configure Jersey JSON procesor itself. Various configuration options could be set on an JSONConfiguration instance. The instance could be then further used to create a JSONConfigurated JSONJAXBContext, which serves as a main configuration point in this area. To pass your specialized JSONJAXBContext to Jersey, you will finally need to implement a JAXBContext ContextResolver:
要实现更重要的 JSON 格式更改,您需要配置 Jersey JSON 处理器本身。可以在 JSONConfiguration 实例上设置各种配置选项。然后可以进一步使用该实例创建一个 JSONConfigurated JSONJAXBContext,作为该区域的主要配置点。要将您的专用 JSONJAXBContext 传递给 Jersey,您最终需要实现一个 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;
}
}
回答by chrset
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?
回答by Lance
I'm using cxf, here is my applicationContext.xml to force array in JSON:
我正在使用 cxf,这是我的 applicationContext.xml 以强制使用 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>
回答by Nicholas Ng
I've struggled quite a bit and found this simple solution
我已经挣扎了很多,找到了这个简单的解决方案
In your pom.xml:
在你的 pom.xml 中:
<dependency>
<groupId>org.codehaus.Hymanson</groupId>
<artifactId>Hymanson-jaxrs</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.Hymanson</groupId>
<artifactId>Hymanson-xc</artifactId>
<version>1.9.13</version>
</dependency>
In your web.xml:
在您的 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.Hymanson.jaxrs</param-value>
</init-param>
回答by Piyush Upadhyay
Converting the Array into ArrayList would suffice the requirement here. Similar kind of contradictory issue I have faced, where I had to return the Json Array Object instead of list in case of single element.
将 Array 转换为 ArrayList 就满足了这里的要求。我遇到过类似的矛盾问题,在单个元素的情况下,我必须返回 Json 数组对象而不是列表。
There i took the help of below annotation to get my job done-
我在下面的注释的帮助下完成了我的工作-
@JsonFormat(with = JsonFormat.Feature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED). Below is the example of a JSON Pojo class:
@JsonFormat(with = JsonFormat.Feature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED)。下面是一个 JSON Pojo 类的例子:
import java.util.List;
import com.fasterxml.Hymanson.annotation.JsonFormat;
import com.fasterxml.Hymanson.annotation.JsonIgnoreProperties;
import com.fasterxml.Hymanson.annotation.JsonProperty;
@JsonIgnoreProperties(ignoreUnknown = true)
public class TAResponseMapper {
@JsonProperty("Response")
@JsonFormat(with = JsonFormat.Feature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED)
private List<TAResponse> responses;
public List<TAResponse> getResponses() {
return responses;
}
public void setResponses(List<TAResponse> responses) {
this.responses = responses;
}
}
回答by eugen
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.
您也可以尝试 Genson 库http://code.google.com/p/genson/。它与 jersey 很好地集成在一起,只需将 jar 放入您的类路径中,一切都会正常工作。它不需要您编写额外的代码,它应该像您现在拥有的那样工作,但没有任何奇怪的结果。
回答by Fabian Lange
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
您可以使用 Jettison(与 Jersey 一起提供)并准备您希望自己使用的结构JSONObject
并JSONArray
作为返回值。它们在包org.codehaus.jettison.json
中jettison-1.3.2.jar
是一个传递依赖jerysey-json