当前位置: 首页 > 知识库问答 >
问题:

使用Jackson反序列化JSON数组

孟子墨
2023-03-14

我收到来自第3方服务提供商的JSON响应,其中包含一系列对象。当我尝试使用Jackson api反序列化JSON时。我收到以下异常

com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of JacksonFields out of START_ARRAY token
 at [Source: java.io.BufferedReader@1015a9e; line: 5, column: 26]

我的回答是

{
    "flags" : 1074200577,
    "results" : {
        "id1" : 0,
        "id2" : 0,
        "fields" : [
            {
                "id1" : 19202,
                "id2" : 19202,
                "count" : 0,
                "format" : 8,
                "type" : "name",
                "flags" : 0,
                "group" : 1074,
                "value" : "1074"
            },
            {
                "id1" : 19218,
                "id2" : 19218,
                "count" : 0,
                "format" : 8,
                "type" : "name",
                "flags" : 0,
                "group" : 1075,
                "value" : "1075"
            }
        ]
    }
}

我的POJO课是这样的

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
class JacksonFields {
    int id1;
    int id2;
    int count;
    int format;
    String type;
    int flags;
    int group;
    String value;

    public JacksonFields(){

    }

    @JsonCreator
    public JacksonFields(@JsonProperty("id1") int id1,
            @JsonProperty("id2") int id2,
            @JsonProperty("count") int count,
            @JsonProperty("format") int format,
            @JsonProperty("type") String type,
            @JsonProperty("flags") int flags,
            @JsonProperty("group") int group,
            @JsonProperty("value") String value){
        this.id1 = id1;
        this.id2 = id2;
        this.count = count;
        this.format = format;
        this.type = type;
        this.flags = flags;
        this.group = group;
        this.value = value;
    }

    public void putId1(int id){
        this.id1=id;
    }

    public void putId2(int id){
        this.id2=id;
    }

    public void putCount(int count){
        this.count=count;
    }

    public void putFormat(int format){
        this.format=format;
    }

    public void putType(String type){
        this.type=type;
    }

    public void putFlag(int flag){
        this.flags=flag;
    }

    public void putGroup(int group){
        this.group=group;
    }

    public void putValue(String val){
        this.value=val;
    }
}


class JacksonResults {
    int id1;
    int id2;
    JacksonFields fields;

    @JsonCreator
    public JacksonResults(@JsonProperty("id1") int id1,
            @JsonProperty("id2") int id2,
            @JsonProperty("fields") JacksonFields fields){
        this.id1 = id1;
        this.id2 = id2;
        this.fields = fields;
    }

    public JacksonResults(){

    }

    public void putId1(@JsonProperty("id1") int id){
        this.id1 = id;
    }

    public void putId2(@JsonProperty("id2") int id){
        this.id2 = id;
    }

    public void putFields(@JsonProperty("fields") JacksonFields fie){
        this.fields = fie;
    }
}


public class JacksonJsonObj{
    Long flags;
    JacksonResults res;

    @JsonCreator
    public JacksonJsonObj(@JsonProperty("flags") long flags, 
            @JsonProperty("results") JacksonResults res){
        this.flags = flags;
        this.res = res;
    }

    public JacksonJsonObj(){

    }

    public void putFlags(@JsonProperty("flags") long flag){
        this.flags = flag;
    }

    public void putResults(@JsonProperty("results") JacksonResults res){
        this.res=res;
    }
}

我正在尝试使用以下代码反序列化JSON

ObjectMapper objmapper = new ObjectMapper();
objmapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
JacksonJsonObj jackobj = objmapper.readValue(new BufferedReader(new inputStreamReader(ipStream)), JacksonJsonObj.class);

如果我试着去做

JacksonJsonObj[] jackobj = objmapper.readValue(new BufferedReader(new inputStreamReader(ipStream)), JacksonJsonObj[].class);

它在BEGIN_对象本身失败。

如何使用数组读取和反序列化JSON。我应该编写自己的反序列化器吗?

编辑如果我使用JSON字符串而不是流,那么我就能够取回所有Java对象。但为了更好的表现,我想让杰克逊继续工作

另一种方式

List<JsonFields> JsonFieldsJackson = new ArrayList<JsonFields>();
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
JsonNode nodes = mapper.readTree(strbuffer.toString());
nodes.elements();
Iterator<JsonNode> iter = nodes.path("results").path("fields").elements();
while(iter.hasNext()){
    JsonNode node = iter.next();
    JsonFields fie = mapper.readValue(node.toString(),JsonFields.class);
    JsonFieldsJackson.add(fie);
}

共有2个答案

薛承志
2023-03-14

要反序列化JSON,应该有3个类,比如

class Field{
int id1;
int id2;
int count;
int format;
String type;
int flags;
int group;
String value;

} 
class Result{
int id1;
int id2;
Field[] fields;
}

class JacksonFields {
String flags;
Result result; 

}

然后你可以像这样写代码

JacksonFields jackobj = objmapper.readValue(new BufferedReader(new inputStreamReader(ipStream)), JacksonFields.class);

然后它会工作。注意:-我没有为您可以提供的类提供适当的注释。

司马狐若
2023-03-14

我认为你们已经有2罐,即1罐。杰克逊核心2。杰克逊地图绘制者

因此,对于从JSON到POJO的解析

    ObjectMapper mapper = new ObjectMapper();
    JavaType javaType=mapper.getTypeFactory().constructType(JacksonFields.class);

    JacksonFields jksnflds = mapper.readValue(jsonString,javaType);

这就是它!

 类似资料:
  • 我目前正在开发一个Java web应用程序,它使用Magento REST API公开的JSON数据。api返回的数据示例如下: 我的应用程序中有一个Java类,如下所示: 我想对数据进行反序列化,并将其转换为,但我总是得到以下错误: 这是我用来将JSON响应反序列化为ArrayList的语句行: 有人能分享一些见解吗?我看到一些例子,返回的JSON对象前面没有任何ID。那是因为我做错了什么吗?非

  • 我似乎很专注于如何去硬化数组数组。我对这些工具很陌生,无法处理JSON文件,我能够去硬化来自国家(https://restcountries.eu/rest/v2/all)的REST应用编程接口的JSON,但我现在正试图从开放天空应用编程接口(https://opensky-network.org/api/states/all?lamin=45.8389 我有这门课: 有能手和二传手 还有这个:

  • 问题内容: 我正在使用Flickr API 。调用该方法时,默认的JSON结果为: 我想将此响应解析为Java对象: JSON属性应按以下方式映射: 不幸的是,我无法找到一种使用Annotations做到这一点的好方法。到目前为止,我的方法是将JSON字符串读入a 并从中获取值。 但是我认为,这是有史以来最不优雅的方式。有没有简单的方法,可以使用注释还是自定义反序列化器? 这对我来说将是很明显的,

  • 我知道我可以创建一个单独的Report类,然后使用@JSONProperty将其嵌入到ReportResponse中。有没有一种方法可以避免这种情况,并用一个注释标记ReportResponse类,将它映射到JSON中的“Report”元素?

  • 我对解析json有一个问题。它有一个日期为exapmle-"2014-01-07"。当它解析并成为createUserRequest.getBirthday()时,它包含-"2014-01-07T04:00:00.000 04:00"。我需要它在createUserRequest对象中,然后我会用另一个对象断言它。问题是如何得到“2014-01-07”? 在CreateUserRequest中,我

  • 如何将jackson JSON映射器与Java 8 LocalDateTime一起使用? JSONMappingException:无法从JSON字符串实例化类型[simple type,class java.time.LocalDateTime]的值;没有单字符串构造函数/工厂方法(通过引用链:mydto[“field1”]->subdto[“date”])