java - 使用 Jackson 序列化和反序列化原始 Json 字符串

标签 java json jackson

我使用 Jackson Fasterxml 版本 2.8.0 来序列化和反序列化 json,如下所示:

public static byte[] serializeData(Object object){
   final ObjectMapper mapper = new ObjectMapper();
   return mapper.writeValueAsBytes(object);
}

public static void main(String [] args) {
  String json = "{ \"id\" : \"user1\" }"; // need to escape or else compiler complains

  byte[] result = serializeData(json);

  final ObjectMapper mapper = new ObjectMapper();
  final JsonNode jsonNode = mapper.readTree(result);

  System.out.println(json);
  System.out.println(jsonNode.toString());
  System.out.println(jsonNode.getNodeType());

  Iterator<String> fields = jsonNode.fieldNames();
  while(fields.hasNext()){
    System.out.println("field - " + fields.next());
  }
}

输出是:

{ "id" : "user1" }
"{ \"id\" : \"user1\" }"
STRING

请注意,没有用于打印字段名称的输出行。因此,看起来 JsonNode 没有任何属性,并且由于某种原因,toString() 中包含转义字符。我是否以错误的方式使用这个库?为什么反序列化字节数组会导致我找不到最初添加的字段?

更新

提供应用程序的更多上下文。应用程序接收 Json 作为字符串输入。反序列化 Json 的代码不知道 Json 的模型。它只是期望它是有效的 Json 对象,以便它可以迭代其中的各个字段。

最佳答案

您将 JSON 字符串误认为是 java 对象,这是这里的关键问题。

  String json = "{ \"id\" : \"user1\" }"; // need to escape or else compiler complains

  byte[] result = serializeData(json);

你的String json只是一个字符串,它的内容是什么并不重要,使用mapper.writeValueAsBytes(object)只是序列化一个字符串,从而产生一个STRING 类型的 JSON 节点。

要序列化具有 String 类型字段 id 的对象,您需要序列化具有 id 类型 String 字段的对象>.

例如:

public class User {
    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "User [id=" + id + "]";
    }
}

此类型的 User 可以序列化为 {"id":"User1"} (如果 id 字段设置为“User1”)。

在下面的示例中,您可以从 POJO (User user = new User();) 开始,也可以从有效的 json 字符串开始 (String json = "{\"id\":\"user1\"}";)。

在第一种情况下,您首先将对象映射到 json 字节,然后解析这些字节以获取 JSONNode(一种 json 的 DOM 树)。

在第二种情况下,您只需解析字节来获取节点,您不会写入json字符串的ValueAsBytes,因为您只需字符串化两次,从而得到STRING类型的值节点。

    User user = new User();
    user.setId("user1");

    ObjectMapper mapper = new ObjectMapper();
    byte[] jsonBytes = mapper.writeValueAsBytes(user);


    System.out.println(new String(jsonBytes)); // will print {"id":"user1"}

    JsonNode node = mapper.readTree(jsonBytes);
    Iterator<String> names = node.fieldNames();
    while (names.hasNext()) {
        String name = (String) names.next();
        JsonNodeType type = node.get(name).getNodeType();
        System.out.println(name+":"+type); //will print id:STRING
    }

    // This is not a object to serialize 
    // This is a string to parse into a json object
    String json = "{ \"id\" : \"user1\" }";

    JsonNode node2 = mapper.readTree(json.getBytes());
    names = node.fieldNames();
    while (names.hasNext()) {
        String name = (String) names.next();
        JsonNodeType type = node.get(name).getNodeType();
        System.out.println(name+":"+type); //will print id:STRING
    }

关于java - 使用 Jackson 序列化和反序列化原始 Json 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43163257/

相关文章:

java - 将值从 Servlet 传递到 JSP

java - Android ImageView 布局问题

java - 如何修复我的maven项目中的mysql版本

json - Jackson @JsonView 没有按预期工作

ruby-on-rails - 在 rails api 事件模型序列化程序中为关联属性使用不同的键名

PHP:对象的最后一个键

java - @JsonInclude(Include.NON_NULL) 不工作/ jackson 序列化空值

java - java 的本地时区问题

java - 重命名所有 JSON 键 - Java - Jackson - spring boot

java - 向字段添加冗余的@JsonProperty值注释是否会提高反序列化性能?