我使用 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/