在下面的示例中,我有一个主类-A和它的子类-B。两者都可以用作一般类X中的属性。
public class A
{
@JsonProperty("primary_key")
public final String primaryKey;
@JsonCreator
A(@JsonProperty("primary_key") String primaryKey)
{
this.primaryKey = primaryKey;
}
}
public class B extends A
{
@JsonProperty("secondary_key")
public final String secondaryKey;
@JsonCreator
B(@JsonProperty("primary_key") String primaryKey, @JsonProperty("secondary_key") String secondaryKey)
{
super(primaryKey);
this.secondaryKey = secondaryKey;
}
}
public class X
{
@JsonProperty("keys")
public final A keys;
@JsonCreator
X(@JsonProperty("keys") A keys)
{
this.keys = keys;
}
}
如何使用Jackson多态特性将以下给定的json正确反序列化为各自的类:
JSON A:
{ "keys" :{
"primary_key" : "abc"
}
}
JSON B:
{ "keys" : {
"primary_key" : "abc",
"secondary_key" : "xyz"
}
}
预期结果:将keys对象映射到JSON A的类A和JSON B的类B。
请提出其他建议。
如果我理解正确,简单地传递值就可以了,无需任何配置。我相信这就是您正在寻找的:
public class Test {
private static final String JSON = "{\"keys\":{\"primary_key\":\"abc\",\"secondary_key\":\"xyz\"}}";
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
X x = mapper.readValue(JSON, X.class);
System.out.println(mapper.writeValueAsString(x));
}
}
class A {
private String primary_key;
public String getPrimary_key() {
return primary_key;
}
public void setPrimary_key(String primary_key) {
this.primary_key = primary_key;
}
}
class B extends A {
private String secondary_key;
public String getSecondary_key() {
return secondary_key;
}
public void setSecondary_key(String secondary_key) {
this.secondary_key = secondary_key;
}
}
class X {
private B keys;
public B getKeys() {
return keys;
}
public void setKeys(B keys) {
this.keys = keys;
}
}
输出将为:
{"keys":{"primary_key":"abc","secondary_key":"xyz"}}
如果这不是您所期望的,请提供另一个解释,我将根据需要编辑答案。
这感觉像是一个非常常见的问题,没有简单的注释方法来解决它(或者我就是找不到):
Jackson多态反序列化-是否可以要求存在字段而不是特定值?
使用Jackson反序列化多态类型
您可以做的一件事是将自定义反序列化器添加到对象映射器中。下面是此方法的演示:https://stackoverflow.com/a/19464580/1032167
下面是与您的示例相关的演示:
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.IOException;
public class Main4 {
private static final String jsonA = "{ \"keys\" : { \"primary_key\" : \"abc\" } }";
private static final String jsonB =
"{ \"keys\" : { \"primary_key\" : \"abc\", \"secondary_key\" : \"xyz\" } }";
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
SimpleModule idAsRefModule = new SimpleModule("ID-to-ref");
idAsRefModule.addDeserializer(A.class, new AJsonDeserializer());
mapper.registerModule(idAsRefModule);
X tl = mapper.readValue(jsonA, X.class);
System.out.println(tl);
X t2 = mapper.readValue(jsonB, X.class);
System.out.println(t2);
}
public static class AJsonDeserializer extends JsonDeserializer<A>{
@Override
public A deserialize(JsonParser jp, DeserializationContext dc)
throws IOException {
ObjectCodec codec = jp.getCodec();
JsonNode node = codec.readTree(jp);
if (node.has("secondary_key")) {
return codec.treeToValue(node, B.class);
}
return new A(node.findValue("primary_key").asText());
}
}
public static class A
{
@JsonProperty("primary_key")
public final String primaryKey;
@JsonCreator
A(@JsonProperty("primary_key") String primaryKey)
{
this.primaryKey = primaryKey;
}
@Override
public String toString() {
return "A{" +
"primaryKey='" + primaryKey + '\'' +
'}';
}
}
public static class B extends A
{
@JsonProperty("secondary_key")
public final String secondaryKey;
@JsonCreator
B(@JsonProperty("primary_key") String primaryKey,
@JsonProperty("secondary_key") String secondaryKey)
{
super(primaryKey);
this.secondaryKey = secondaryKey;
}
@Override
public String toString() {
return "B{" +
"primaryKey='" + primaryKey + '\'' +
"secondaryKey='" + secondaryKey + '\'' +
'}';
}
}
public static class X
{
@JsonProperty("keys")
public final A keys;
@JsonCreator
X(@JsonProperty("keys") A keys)
{
this.keys = keys;
}
@Override
public String toString() {
return "X{" +
"keys=" + keys +
'}';
}
}
}
但是如果你想使用默认的反序列化器,你必须再创建一个超类,或者看这里如何解决这个问题:https://stackoverflow.com/a/18405958/1032167
好的,我知道有一堆类似的问题,但似乎都行不通。 我为我的实体设置了以下结构。 在我的控制器中,我尝试将一个请求映射到下面的方法。 请尝试%1 我认为它是这样做的--添加了一个元数据属性,该属性将存储子类类。 结果是什么。 结果是什么。 即使将和添加到这两个子类中,也会得到相同的结果。 其他尝试 我试了很多。什么都不起作用。不会包含这里的所有内容。 我觉得应该有一个简单的方法来做到这一点,但我只是不
我有一个带有几个实现类的通用接口,需要通过Json序列化和反序列化这些类。我正试图开始与Jackson合作,使用完整的数据绑定,没有太多运气。 示例代码说明了这个问题: 调用会导致以下异常: 组织。科德豪斯。杰克逊。地图JsonMappingException:未找到类测试$Success的序列化程序,也未找到创建BeanSerializer的属性(为了避免异常,请禁用SerializationC
将有更多的类(不同的产品)扩展。 当我使用序列化它时, 这是输出: 将引发此异常: java.lang.IllegalArgumentException:意外的标记(VALUE_STRING),应为field_name:缺少包含类型id(类com.shubham.model.product的)的属性“type”,位于[源:n/a;行:-1,列:-1] 我在这里做错了什么?我观察了一下,发现了一个问
问题内容: 在使用Jackson(fasterxml.jackson 2.1.1)时,是否有内置的方式仅序列化子的ID?我们要发送一个通过REST的参考文件。但是person对象非常复杂,我们可以在服务器端刷新它,因此我们需要的只是主键。 还是我需要一个定制的序列化器?还是我需要其他所有属性?这样可以防止在请求对象时将数据发送回去吗?我不确定是否需要,但我想尽可能控制它。 问题答案: 有几种方法。
臣接孙氏道: 我如何使Jersey解析JSONs,以便如果eventType=1,那么stats.params变成Params1的实例,而else变成params2的实例?
我正在尝试使用JSON ObjectMapper反序列化对象。我在尝试反序列化时看到以下错误