如何使用Jackson在对象中包含原始JSON?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (36)

当使用Jackson(反序列化)对象时,我试图在Java对象中包含原始JSON。为了测试此功能,我编写了以下测试:

public static class Pojo {
    public String foo;

    @JsonRawValue
    public String bar;
}

@Test
public void test() throws JsonGenerationException, JsonMappingException, IOException {

    String foo = "one";
    String bar = "{\"A\":false}";

    Pojo pojo = new Pojo();
    pojo.foo = foo;
    pojo.bar = bar;

    String json = "{\"foo\":\"" + foo + "\",\"bar\":" + bar + "}";

    ObjectMapper objectMapper = new ObjectMapper();
    String output = objectMapper.writeValueAsString(pojo);
    System.out.println(output);
    assertEquals(json, output);

    Pojo deserialized = objectMapper.readValue(output, Pojo.class);
    assertEquals(foo, deserialized.foo);
    assertEquals(bar, deserialized.bar);
}

代码输出如下一行:

{"foo":"one","bar":{"A":false}}

JSON正是我想要的样子。不幸的是,当试图将JSON读入对象时,代码会失败,但会出现异常。这是一个异常:

org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token at [Source: java.io.StringReader@d70d7a; line: 1, column: 13] (through reference chain: com.tnal.prism.cobalt.gather.testing.Pojo["bar"])

提问于
用户回答回答于

@JsonRawValue只用于序列化端,因为相反的方向处理起来有点棘手。实际上,它是为了允许注入预编码内容而添加的。

内容必须被解析,然后重新写回“原始”形式,这可能是相同的,也可能不是相同的(因为字符引用可能不同)。这是一般的案子。但也许这对某些问题是有意义的。

针对您的具体情况,可以将类型指定为‘java.lang.Object’,

用户回答回答于

public class Pojo {
  Object json;

  @JsonRawValue
  public String getJson() {
    // default raw value: null or "[]"
    return json == null ? null : json.toString();
  }

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

下面是工作测试:

public class PojoTest {
  ObjectMapper mapper = new ObjectMapper();

  @Test
  public void test() throws IOException {
    Pojo pojo = new Pojo("{\"foo\":18}");

    String output = mapper.writeValueAsString(pojo);
    assertThat(output).isEqualTo("{\"json\":{\"foo\":18}}");

    Pojo deserialized = mapper.readValue(output, Pojo.class);
    assertThat(deserialized.json.toString()).isEqualTo("{\"foo\":18}");
    // deserialized.json == {"foo":18}
  }
}

扫码关注云+社区