【问题标题】:Spring deserialize object with JSONObject fieldSpring使用JSONObject字段反序列化对象
【发布时间】:2019-01-30 17:31:27
【问题描述】:

我在 spring 中反序列化包含 JSON 字段的对象时遇到问题。我有一个DataTable 数据结构,它既有字符串字段,也有一个应该包含 JSONObject 的字段:

public class DataTable {

        private String identifier;  
        private String version;         
        private JSONObject content;

        //getters and setters 
}

我希望能够持久化这个对象并在以后检索它。 当我将这样的DataTable 对象发布到我的控制器并尝试稍后检索它时,我的content 字段将为空,无论我发布的内容如何:

{
  "identifier": "id1",
  "version": "0.0.1",
  "content": {
    "empty": true
  }
}

jackson 似乎无法正确反序列化 JSONObject 类型字段,而是将其留空。如何使其正确反序列化字段?

【问题讨论】:

  • 不确定,但我认为使用 Gson 可以解决您的问题。 See:

标签: java json spring rest jackson


【解决方案1】:

Jackson 有jackson-datatype-json-org 模块,它允许我们将 json.org 对象与 POJO 组合或反序列化为 json.org 对象作为顶级对象。

<dependency>
  <groupId>com.fasterxml.jackson.datatype</groupId>
  <artifactId>jackson-datatype-json-org</artifactId>
  <version>${jackson2.version}</version>
</dependency>

这是一个测试(别忘了注册JsonOrgModule)。

public class JsonOrgJacksonTest {

    private final String json =
            "{" +
            "  \"id\": \"one\"," +
            "  \"content\": {" +
            "    \"foo\": \"bar\"," +
            "    \"baz\": \"blah\"" +
            "  }" +
            "}";

    @Test
    public void testJsonOrg() throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new JsonOrgModule());

        Model model = mapper.readValue(json, Model.class);

        assertThat(model.getId()).isEqualTo("one");
        assertThat(model.getContent().get("foo")).isEqualTo("bar");
        assertThat(model.getContent().get("baz")).isEqualTo("blah");
    }

    public static class Model {
        private String id;
        private JSONObject content;

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

        public JSONObject getContent() { return content; }
        public void setContent(JSONObject content) { this.content = content; }
    }
}

【讨论】:

    【解决方案2】:

    JSONObject 不应该被序列化。它是供内部使用的。如果您想在没有模型(专用类)的情况下使用此数据结构的 JSON 表示,请尝试将其转换为 Map。

    Map<String,Object> result =
        new ObjectMapper().readValue(dataTable.getContent(), HashMap.class);
    

    【讨论】:

      【解决方案3】:

      您可以为此使用自定义反序列化器:

      public class Test {
        public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
          ObjectMapper mapper = new ObjectMapper();
          final SimpleModule module = new SimpleModule("configModule",   Version.unknownVersion());
          module.addDeserializer(DataTable.class, new DeSerializer());
          mapper.registerModule(module);
          // DataTable readValue = mapper.readValue(<xml source>);
        }
      }
      
      class DeSerializer extends StdDeserializer<DataTable> {
      
        protected DeSerializer() {
          super(DataTable.class);
        }
      
        @Override
        public DataTable deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
          // use p.getText() and p.nextToken to navigate through the xml and construct DataTable object
          return new DataTable();
      
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-07-06
        • 1970-01-01
        • 1970-01-01
        • 2011-03-18
        • 1970-01-01
        • 1970-01-01
        • 2015-09-01
        • 1970-01-01
        相关资源
        最近更新 更多