使用Jackson将嵌套JSON转换为对象并从对象转换为JSON

4
我下面有一个实体类,包含两个字符串字段:name和description。其中description字段应该包含原始的JSON值,例如{ "abc": 123 }。
@Getter
@Setter
public class Entity {
    private String name;

    @JsonRawValue
    private String descriptionJson; 
}

我有一份使用Jackson进行序列化和反序列化的简单测试代码,如下所示:

Entity ent = new Entity();
ent.setName("MyName");
ent.setDescriptionJson("{ \"abc\": 123 }");

// Convert Object to JSON string
String json = mapper.writeValueAsString(ent);

// Convert JSON string back to object
Entity ent2 = mapper.readValue(json, Entity.class);

在将对象转换为JSON时,当设置@JsonRawValue时,描述字符串会被嵌套:

{"name":"MyName","descriptionJson":{ "abc": 123 }}

然而,当我调用Jackson mapper.readValue函数将JSON字符串读回实体对象时,我会遇到异常:

com.fasterxml.jackson.databind.exc.MismatchedInputException:
Cannot deserialize instance of `java.lang.String` out of START_OBJECT token 
at [Source: (String)"{"name":"MyName","descriptionJson":{ "abc": 123 }}"; line: 1, column: 36] (through reference chain: com.test.Entity["descriptionJson"])

考虑到存在@JsonRawValue注解,您如何建议将创建的JSON字符串编组回实体对象?是否还有其他我需要了解的注解?
谢谢。
4个回答

4
@JsonRawValue 是专门用于序列化的,但是在这个问题中,你可以像这样做:
@Getter
@Setter
public class Entity {

    private String name;

    @JsonRawValue
    private String descriptionJson;

    @JsonProperty(value = "descriptionJson")
    public void setDescriptionJsonRaw(JsonNode node) {
        this.descriptionJson = node.toString();
    }
}

这个问题与 如何使用Jackson在对象中包含原始JSON 重复。

1

为了满足我的需求,我使用了Map类型的字段来存储Json。这样我就能够把嵌套的Json读入为Map,并且在将对象序列化为JSON时,它能够正常显示。下面是一个例子。

Entity.java

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;

import java.util.HashMap;
import java.util.Map;

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class Entity {
    public int id=0;
    public String itemName="";
    public Map<String,String> owner=new HashMap<>();
}

Temp.java

import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;

public class Temp {

public static void main(String[] args){

    ObjectMapper objectMapper= new ObjectMapper();
    try {
        Entity entity 
=objectMapper.readValue(Temp.class.getResource("sample.json"), Entity.class);
        System.out.println(entity);
        String json=objectMapper.writeValueAsString(entity);
        System.out.println(json);
    } catch (IOException e) {
        e.printStackTrace();
    }


    }
}

Sample.json

{
  "id": 1,
  "itemName": "theItem",
  "owner": {
    "id": 2,
    "name": "theUser"
  }
}

0
您可以按照以下方式使用Jackson 2中的ObjectMapper:

ObjectMapper mapper = new ObjectMapper();
String jsonStr = "sample json string"; // populate this as required
MyClass obj = mapper.readValue(jsonStr,MyClass.class)

尝试转义描述 JSON 值中的花括号。

0

@JsonRawValue 仅用于序列化,参见文档

标记注解,表示应将注释方法或字段序列化为直接包含属性的文本字符串值,而不引用字符。

为解决您的问题,您可以尝试以下方法:

public class Entity {
    @Getter
    @Setter
    private String name;

    private String descriptionJson;

    @JsonRawValue
    public String getDescriptionJson() {
        return descriptionJson;
    }

    public void setJson(JsonNode node) {
        this.descriptionJson = node.toString();
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接