多种类型的 Jackson 反序列化接口
Jackson deserialization interface on multiple types
我正在 Java 中试验 Jackson 反序列化的一些问题。我做了2个解决方案,都无法解决问题。问题?我得到了 属性 重复的结果,这是一个在 jackson 反序列化后重复的字段。 (我的问题和这个问题一模一样:而且当时没人能给你答案)
首先,我有以下 class:
@JsonIgnoreProperties(ignoreUnknown = true)
public class Instance {
@JsonProperty("id")
private String id;
@JsonProperty("name")
private String name;
@JsonProperty("type")
private InstanceType type;
}
我想做的只是实例化一个 'Instance' 类型的对象,保存并读取它。对于解决方案 2,对象以重复的类型保存(类型显示为包含 'name'、'firs_type' 的数组,例如或 'second_type)取决于我创建的内容。使用解决方案 1,我可以保存对象 ok,但是当我尝试读取它时,我遇到了 jackson 异常转换。
方案一:
@JsonDeserialize(using = InstanceTypeDeserializer.class)
public interface InstanceType {
String value();
}
@JsonDeserialize(as = HardInstanceType.class)
public enum HardInstanceType implements InstanceType {
FIRST_TYPE("first_type"),
SECOND_TYPE("second_type")
private String value;
HardInstanceType(String value) {
this.value = value;
}
@JsonValue
public String value() {
return value;
}
}
@JsonDeserialize(as = SoftInstanceType.class)
public enum SoftInstanceType implements InstanceType {
//.. types implementaion similar as HardInstanceType
}
public class InstanceTypeDeserializer extends JsonDeserializer<InstanceType> {
@Override
public InstanceType deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
ObjectMapper mapper = (ObjectMapper) jp.getCodec();
ObjectNode root = (ObjectNode) mapper.readTree(jp);
if(root.get("name").asText().equals("hard")) {
return mapper.readValue(root.toString(), HardInstanceType.class);
} else {
return mapper.readValue(root.toString(), SoftInstanceType.class);
}
}
}
此解决方案的问题是,当我尝试获取存储的数据并映射到 class 时,出现以下错误:
exception parsing json:
com.fasterxml.jackson.databind.JsonMappingException: class
com.fasterxml.jackson.databind.node.TextNode cannot be cast to class
com.fasterxml.jackson.databind.node.ObjectNode
(com.fasterxml.jackson.databind.node.TextNode and
com.fasterxml.jackson.databind.node.ObjectNode are in unnamed module
of loader org.springframework.boot.loader.LaunchedURLClassLoader
@1a3e8e24) (through reference chain:
java.util.ArrayList[0]->com.project.package.xxxx.Instance["type"])
方案二
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "name")
@JsonSubTypes({
@JsonSubTypes.Type(value = HardInstanceType.class, name = "hard") })
public interface InstanceType {
String value();
}
这个解决方案的问题是,当我保存数据时,当我创建一个实例对象并将其存储在存储的数据中时,我得到以下内容:
"id": "1",
"name": "hard",
"type": [
"hard",
"first_type"
]
哪里不对,类型应该是store just "first_type"(用解决方案1存储的,但我看不懂哈哈)。
当然Instaceclass比较复杂,字段也比较多,我这里缩减了,只是为了举例。
我需要这方面的帮助,非常感谢。
终于可以解决问题了。
我 post 这是为了以防万一其他人需要它。
将 属性 添加到我的 HardInstanceType class。
public enum HardInstanceType 实现 InstanceType {
FIRST_TYPE("first_type"),
SECOND_TYPE("second_type");
private String value;
public String hardTypeIdentifierSer = "hardTypeIdentifierSer";
HardInstanceType(String value) {
this.value = value;
}
@JsonValue
public String value() {
return value;
}
}
然后,在解串器中:
public class InstanceTypeDeserializer 扩展 JsonDeserializer {
@Override
public InstanceType deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
TreeNode node = jp.readValueAsTree();
if (node.get("hardTypeIdentifierSer") != null) {
return jp.getCodec().treeToValue(node, HardInstanceType.class);
}
}
我正在 Java 中试验 Jackson 反序列化的一些问题。我做了2个解决方案,都无法解决问题。问题?我得到了 属性 重复的结果,这是一个在 jackson 反序列化后重复的字段。 (我的问题和这个问题一模一样:
首先,我有以下 class:
@JsonIgnoreProperties(ignoreUnknown = true)
public class Instance {
@JsonProperty("id")
private String id;
@JsonProperty("name")
private String name;
@JsonProperty("type")
private InstanceType type;
}
我想做的只是实例化一个 'Instance' 类型的对象,保存并读取它。对于解决方案 2,对象以重复的类型保存(类型显示为包含 'name'、'firs_type' 的数组,例如或 'second_type)取决于我创建的内容。使用解决方案 1,我可以保存对象 ok,但是当我尝试读取它时,我遇到了 jackson 异常转换。
方案一:
@JsonDeserialize(using = InstanceTypeDeserializer.class)
public interface InstanceType {
String value();
}
@JsonDeserialize(as = HardInstanceType.class)
public enum HardInstanceType implements InstanceType {
FIRST_TYPE("first_type"),
SECOND_TYPE("second_type")
private String value;
HardInstanceType(String value) {
this.value = value;
}
@JsonValue
public String value() {
return value;
}
}
@JsonDeserialize(as = SoftInstanceType.class)
public enum SoftInstanceType implements InstanceType {
//.. types implementaion similar as HardInstanceType
}
public class InstanceTypeDeserializer extends JsonDeserializer<InstanceType> {
@Override
public InstanceType deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
ObjectMapper mapper = (ObjectMapper) jp.getCodec();
ObjectNode root = (ObjectNode) mapper.readTree(jp);
if(root.get("name").asText().equals("hard")) {
return mapper.readValue(root.toString(), HardInstanceType.class);
} else {
return mapper.readValue(root.toString(), SoftInstanceType.class);
}
}
}
此解决方案的问题是,当我尝试获取存储的数据并映射到 class 时,出现以下错误:
exception parsing json: com.fasterxml.jackson.databind.JsonMappingException: class com.fasterxml.jackson.databind.node.TextNode cannot be cast to class com.fasterxml.jackson.databind.node.ObjectNode (com.fasterxml.jackson.databind.node.TextNode and com.fasterxml.jackson.databind.node.ObjectNode are in unnamed module of loader org.springframework.boot.loader.LaunchedURLClassLoader @1a3e8e24) (through reference chain: java.util.ArrayList[0]->com.project.package.xxxx.Instance["type"])
方案二
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "name")
@JsonSubTypes({
@JsonSubTypes.Type(value = HardInstanceType.class, name = "hard") })
public interface InstanceType {
String value();
}
这个解决方案的问题是,当我保存数据时,当我创建一个实例对象并将其存储在存储的数据中时,我得到以下内容:
"id": "1",
"name": "hard",
"type": [
"hard",
"first_type"
]
哪里不对,类型应该是store just "first_type"(用解决方案1存储的,但我看不懂哈哈)。
当然Instaceclass比较复杂,字段也比较多,我这里缩减了,只是为了举例。
我需要这方面的帮助,非常感谢。
终于可以解决问题了。 我 post 这是为了以防万一其他人需要它。
将 属性 添加到我的 HardInstanceType class。
public enum HardInstanceType 实现 InstanceType {
FIRST_TYPE("first_type"), SECOND_TYPE("second_type"); private String value; public String hardTypeIdentifierSer = "hardTypeIdentifierSer"; HardInstanceType(String value) { this.value = value; } @JsonValue public String value() { return value; }
}
然后,在解串器中:
public class InstanceTypeDeserializer 扩展 JsonDeserializer {
@Override public InstanceType deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { TreeNode node = jp.readValueAsTree(); if (node.get("hardTypeIdentifierSer") != null) { return jp.getCodec().treeToValue(node, HardInstanceType.class); }
}