Jackson JsonParser在Json读取阵列失败了

时间:2014-03-25 15:08:24

标签: java json jackson

我有一个像这样的Json结构

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

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

我的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);
                }
            }
        }           
    }

}

所有我想要的是通过令牌解析整个json令牌并获取文本。但是while (jp.nextToken() != JsonToken.END_OBJECT)行在遇到“'}时会失败。在数组中。我从昨天起就被困在这里并尝试了其他一些技巧,但没有任何结果。我们还有另外一种做法吗?我的JSON结构看起来不错吗?请告诉我哪里出错了。谢谢!

2 个答案:

答案 0 :(得分:0)

首先:

  

[Doe]我的JSON结构看起来好吗?

是和否。虽然您的JSON是合法的,但由于重复键,您将遇到问题:

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

此事件中JSON解析器的行为是不可预测的,even RFC 7159 says so(是的,RFC 4627已被取代)。不幸的是,重复的密钥仍然不被禁止。

所以,这是合法的,但不是理智的。改为使用数组:

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

除此之外,与杰克逊一起阅读JSON就是这样做的:

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

然后,您可以使用JsonNode的全部功能。

答案 1 :(得分:0)

你不能在json中拥有相同名称的字段,你可以,但它不能像你的情况那样被解析。

我假设您为每个用户设置了array of users namedetails个文件。

这是与您的User class对应的候选Java类:

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;
    }
}

使用逆向工程可以看到如何反序列化用户列表;

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));

}

用户列表的结果是:

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

正如您所看到的,它与您的JSON字符串不同。

<强>更新 如果您想在两个单独的容器中保存名称和详细信息......;

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));
}

结果JSON是;

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