简体   繁体   English

Jackson JsonParser无法读取Json中的数组

[英]Jackson JsonParser fails reading an array in Json

I have a Json Structure something like this 我有一个像这样的Json结构

{
"name" : "abcd",
"details" : [{"city":"string", "zipcode":"integer"}],

"name" : "qwert",
"details" : [{"address":"long", "state":"string"}]
}

And my java code looks like below 我的Java代码如下所示

public class JsonTest {

    public static void main(String[] args) throws JsonParseException, IOException {

        JsonFactory jf = new JsonFactory(); 
        JsonParser jp = jf.createParser(new File("C:\\sample.json"));

        while (jp.nextToken() != JsonToken.END_OBJECT)
        {
            String jsonField = jp.getCurrentName();

            if ("name".equalsIgnoreCase(jsonField))
            {
                jp.nextToken();
                System.out.println(jp.getText());
            }

            if ("details".equalsIgnoreCase(jsonField))
            {
                jp.nextToken();
                while (jp.nextToken() != JsonToken.END_ARRAY)
                {
                    jp.nextToken();
                    String field = jp.getText();
                    System.out.println(field);
                }
            }
        }           
    }

}

All am trying to do is parse the whole json token by token and get the text. 我要做的就是逐个令牌解析整个json令牌并获取文本。 But the line while (jp.nextToken() != JsonToken.END_OBJECT) fails when it encounters a '}' in the array. 但是, while (jp.nextToken() != JsonToken.END_OBJECT)数组中遇到“}”时失败。 Am just stuck here since yesterday and experimenting with several other tricks but nothing works out. 从昨天开始,我就一直呆在这里,并尝试了其他一些技巧,但没有成功。 Do we have another way doing this? 我们还有其他方法吗? Is my JSON structure looks okay? 我的JSON结构好吗? Please tell me where am going wrong. 请告诉我哪里出了问题。 Thanks! 谢谢!

First of all: 首先:

[Doe]s my JSON structure look[s] okay? [我的JSON结构看起来好吗?

Yes and no. 是的,没有。 while your JSON is legal, you are going to have a problem because of duplicate keys: 虽然您的JSON合法,但是由于重复的密钥,您将遇到问题:

{
    "name": "xxx",
    "name": "yyy"
}

The behaviour of a JSON parser in this event is unpredictable, even RFC 7159 says so (yes, RFC 4627 has been superseded). JSON分析器在此事件中的行为是无法预测的, 即使RFC 7159也是如此 (是的,RFC 4627已被取代)。 Unfortunately, duplicate keys are still not forbidden. 不幸的是, 仍然不允许重复的密钥。

So, it is legal, but not sane. 因此,这是合法的,但不是理智的。 Use an array instead: 改用数组:

[ { "name": "xxx", "details": "whatever" }, "etc" ]

This aside, reading JSON with Jackson is done as this: 除此之外,用Jackson读取JSON的操作如下:

final ObjectMapper mapper = new ObjectMapper();
final JsonNode node = mapper.readTree(yourFileHere);

You can then use the full power of JsonNode . 然后,您可以使用JsonNode的全部功能。

You cannot have fields with the same name in a json, well you can but it could not be parsed as in your case. 您不能在json中具有相同名称的字段,但是可以,但是无法像您的情况一样进行解析。

I assume you have an array of users with name and details fileds for each user. 我假设您有一个array of users其中包含每个用户的namedetails name

Here is a candidate Java class corresponding to your User class : 这是与您的User class相对应的候选Java User class

public class TestUser implements Serializable {
    String name;
    List<Map<String, String>> details = new ArrayList<Map<String, String>>();

    TestUser() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Map<String, String>> getDetails() {
        return details;
    }

    public void setDetails(List<Map<String, String>> details) {
        this.details = details;
    }
}

with reverse engineering lets see how is a list of users are de-serialized; 通过反向工程,可以查看如何对用户列表进行反序列化;

public static void main(String[] args) throws IOException {
    List<TestUser> testUsers = new ArrayList<TestUser>();

    TestUser testUser1 = new TestUser();
    testUser1.name = "abcd";
    HashMap<String, String> detailsHashMap = new HashMap<String, String>();
    detailsHashMap.put("city", "string");
    detailsHashMap.put("zipcode", "integer");
    testUser1.details.add(detailsHashMap);
    testUsers.add(testUser1);

    TestUser testUser2 = new TestUser();
    testUser2.name = "qwert";
    detailsHashMap = new HashMap<String, String>();
    detailsHashMap.put("address", "long");
    detailsHashMap.put("state", "string");
    testUser2.details.add(detailsHashMap);
    testUsers.add(testUser2);

    ObjectMapper mapper = new ObjectMapper();

    System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(testUsers));

}

and the outcome of the users list is: 用户列表的结果是:

[ {
  "name" : "abcd",
  "details" : [ {
    "zipcode" : "integer",
    "city" : "string"
  } ]
}, {
  "name" : "qwert",
  "details" : [ {
    "address" : "long",
    "state" : "string"
  } ]
} ]

As you can see it is different from your JSON string. 如您所见,它与JSON字符串不同。

UPDATE If you want to hold names and details in two separate containers...; 更新如果要在两个单独的容器中保存名称和详细信息...;

public static class Container {
    List<String> names = new ArrayList<String>();
    Map<String, String> details = new HashMap<String, String>();

    public Container() {
    }

    public List<String> getNames() {
        return names;
    }

    public void setNames(List<String> names) {
        this.names = names;
    }

    public Map<String, String> getDetails() {
        return details;
    }

    public void setDetails(Map<String, String> details) {
        this.details = details;
    }
}

....
public static void main(String[] args) throws IOException {

    Container container = new Container();
    container.names.add("abcd");
    container.names.add("qwert");
    container.details.put("city", "string");
    container.details.put("zipcode", "integer");
    container.details.put("address", "long");
    container.details.put("state", "string");

    ObjectMapper mapper = new ObjectMapper();
    System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(container));
}

and the outcome JSON is; 结果JSON是;

{
  "names" : [ "abcd", "qwert" ],
  "details" : {
    "address" : "long",
    "zipcode" : "integer",
    "state" : "string",
    "city" : "string"
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM