Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java json反序列化问题_Java_Json_Gson_Jackson - Fatal编程技术网

Java json反序列化问题

Java json反序列化问题,java,json,gson,jackson,Java,Json,Gson,Jackson,有一个数组,当大小为1时,我收到的json数据不包含[];像 {"firstname":"tom"} 当大小大于1时,我收到的数据包含[],如 [{"firstname":"tom"},{"firstname":"robert"}] 当前我的类包含一个数组属性 String[] firstname; //getter setter omit here 处理此问题的代码 ObjectMapper mapper = new ObjectMapper(); MyClass object

有一个数组,当大小为1时,我收到的json数据不包含
[]
;像

{"firstname":"tom"}
当大小大于1时,我收到的数据包含
[]
,如

[{"firstname":"tom"},{"firstname":"robert"}]
当前我的类包含一个数组属性

String[] firstname;
//getter setter omit here
处理此问题的代码

ObjectMapper mapper = new ObjectMapper();    
MyClass object = mapper.readValue(json, MyClass.class);
当大小大于1时,反序列化工作。但是,当大小为1时,反序列化失败

我目前正在使用jackson,这个问题有什么解决方案吗


我想知道jackson/gson或任何其他库是否可以处理这个问题?

编辑:我猜您只需提取一个
jsonement
并检查它是
isJsonArray()
和/或
isJsonObject()
。然后,只需调用
getAsJsonArray()
getAsJsonObject()

旧答案:如果失败,为什么不尝试提取数组并捕获
JsonParseException
。在catch块中,尝试提取对象


我知道它不漂亮,但它应该能工作。

在第一种情况下,它看起来像一个对象,在第二种情况下,它看起来像一个对象数组(听起来像你期望的那样)


对于这种情况,JSON编码库通常有一个“force array”选项。否则,您可以在客户端上检查JSON响应,如果它不是数组,则将返回的对象推送到新数组中。

下面介绍如何使用GSON。让我们假设这个对象结构:

public class Group{

    public Group(final List<Person> members){
        this.members = members;
    }

    private final List<Person> members;
}

public class Person{

    public Person(final String firstName, final String lastName){
        this.firstName = firstName;
        this.lastName = lastName;
    }

    private final String firstName;
    private final String lastName;
}
公共类组{
公共组(最终成员名单){
这个.成员=成员;
}
非公开最终名单成员;
}
公共阶层人士{
公众人物(最终字符串姓氏,最终字符串姓氏){
this.firstName=firstName;
this.lastName=lastName;
}
私有最终字符串名;
私有最终字符串lastName;
}
下面是一个反序列化程序,它可以理解单人条目及其数组:

public class GroupDeserializer implements JsonDeserializer<Group>{

    @Override
    public Group deserialize(final JsonElement json,
        final Type typeOfT,
        final JsonDeserializationContext context) throws JsonParseException{
        List<Person> members;
        if(json.isJsonArray()){
            final JsonArray array = json.getAsJsonArray();
            members = new ArrayList<Person>(array.size());
            for(final JsonElement personElement : array){
                members.add(getSinglePerson(personElement, context));
            }
        } else{
            members =
                Collections.singletonList(getSinglePerson(json, context));
        }
        return new Group(members);
    }

    private Person getSinglePerson(final JsonElement element,
        final JsonDeserializationContext context){
        final JsonObject personObject = element.getAsJsonObject();
        final String firstName =
            personObject.getAsJsonPrimitive("firstname").getAsString();
        final String lastName =
            personObject.getAsJsonPrimitive("lastname").getAsString();
        return new Person(firstName, lastName);
    }

}
公共类GroupDeserializer实现JsonDeserializer{
@凌驾
公共组反序列化(最终JsonElement json,
最终类型typeOfT,
最终JsonDeserializationContext)抛出JsonParseException{
成员名单;
if(json.isJsonArray()){
final-JsonArray数组=json.getAsJsonArray();
members=newarrayList(array.size());
for(最终JsonElement个人元素:数组){
添加(getSinglePerson(personElement,context));
}
}否则{
成员=
Collections.singletonList(getSinglePerson(json,context));
}
返回新组(成员);
}
private Person getSinglePerson(最终JsonElement元素,
最终JsonDeserializationContext(上下文){
final JsonObject personObject=element.getAsJsonObject();
最终字符串名=
personObject.getAsJsonPrimitive(“firstname”).getAsString();
最终字符串lastName=
personObject.getAsJsonPrimitive(“lastname”).getAsString();
返回新人员(名字、姓氏);
}
}

这里您可以找到

对于Jackson,您最好先绑定到JsonNode或对象,如:

Object raw = objectMapper.readValue(json, Object.class); // becomes Map, List, String etc
然后检查你得到了什么,再次绑定:

MyClass[] result;
if (raw instanceof List<?>) { // array
  result = objectMapper.convertValue(raw, MyClass[].class);
} else { // single object
  result = objectMapper.convertValue(raw, MyClass.class);
}
MyClass[]结果;
if(列表的原始实例){//array
结果=objectMapper.convertValue(原始,MyClass[].class);
}else{//单个对象
结果=objectMapper.convertValue(原始,MyClass.class);
}

但我认为你得到的JSON是不好的——为什么你只返回一个大小为1的数组的对象,或者数组,intead呢因此,如果可能的话,我宁愿先修复JSON。但是,如果这不可能,这也会起作用。

我在尝试反序列化由XML构造的JSON对象时遇到了同样的问题。(XML-JSON)。经过相当多的研究,我们发现我们有一个简单的修复

只需设置特性:接受单个值作为数组

ObjectMapper mapper=新的ObjectMapper(); configure(反序列化功能。接受单个值作为数组,true)


更多信息:

您的问题令人困惑;请举例说明。你从哪里收到数据?你是怎么打印的?你用的是哪段代码?有什么事吗?加上细节。数据来自web服务。我不认为大多数库对此有默认处理,因为这不是一种建模数据的好方法。如果可能的话,我会修复数据以使用数组,而不是针对单个元素的情况进行“优化”。这个问题发生在@ResponseBody上的Jackson身上,我无法控制它。你知道吗?我真的不想一个接一个地处理这样的异常。我相信这是一个常见的情况,应该有一个优雅的解决方案。足够公平。尽管根据,这只是一个例外。我可以从客户端“强制数组”吗?我无法控制服务器响应。这是一个很好的例子(也是Java让我伤心的原因:-)请记住,这只是Gson方法,其他软件包也有其他解决方案。请注意,对于这样的解决方案,不必“手动”反序列化Person对象,因为Person不需要自定义处理。只需使用Person=context.deserialize(json,Person.class);(假设还使用了命名策略将JSON元素名与Java字段名相匹配。)@pro b:Cool,很高兴知道。我自己对Gson还比较陌生,这在spring环境中对我很有效。这似乎是最简单的解决办法。