我在春季遇到反序列化包含JSON字段的对象的问题。我有一个DataTable
数据结构,它同时具有String字段和应包含JSONObject的字段:
public class DataTable {
private String identifier;
private String version;
private JSONObject content;
//getters and setters
}
我希望能够保留该对象并在以后检索它。
当我将这样的DataTable
对象发布到Controller并稍后尝试检索它时,无论发布的内容如何,我的content
字段都将为空:
{
"identifier": "id1",
"version": "0.0.1",
"content": {
"empty": true
}
}
杰克逊似乎无法正确反序列化JSONObject
类型字段,而只是将其留空。如何使其正确反序列化字段?
答案 0 :(得分:2)
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; }
}
}
答案 1 :(得分:1)
不应该对JSONObject进行序列化。它仅供内部使用。如果您想在没有模型(专用类)的情况下使用此数据结构的JSON表示,请尝试将其转换为Map。
Map<String,Object> result =
new ObjectMapper().readValue(dataTable.getContent(), HashMap.class);
答案 2 :(得分:1)
您可以为此使用自定义反序列化器:
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();
}
}