简体   繁体   English

通过现场进行杰克逊多态反序列化

[英]Jackson Polymorphic Deserialization via field

let's say, i have a class 假设我有一堂课

public class A{
  private UUID typeId;
  private B data;
}

public abstract class B{
  private String a;
}

public class BChildOne extends B{
  ... some variables
}

public class BChildTwo  extends B{
  ... some variables
}

type of class B is changing, according to A's typeId , so if typeId of A is "XXX", type of data field is BChildOne, and if typeId of A is "YYY", type of data field is BChildTwo. 根据A的typeId,类B的类型正在更改,因此,如果A的typeId为“ XXX”,则数据字段的类型为BChildOne,如果A的typeId为“ YYY”,则数据字段的类型为BChildTwo。

how can i achive that? 我怎样才能做到这一点?

so for i tried that; 所以我尝试过

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility =
JsonAutoDetect.Visibility.NONE, setterVisibility = 
JsonAutoDetect.Visibility.NONE)
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = 
JsonTypeInfo.As.EXTERNAL_PROPERTY , property = "typeId")
@JsonSubTypes({
 @JsonSubTypes.Type(value = BChildOne.class, name = "40ad2fe6-e672-4f0e- 
986e- 
 619c7a1a3223") }
 )
 public abstract class B{

but i got following error; 但是我出现了以下错误;

Unexpected token (END_OBJECT), expected FIELD_NAME: missing property 'typeId' that is to contain type id (for class B) 意外的令牌(END_OBJECT),预期的FIELD_NAME:缺少要包含类型ID(针对类B)的属性“ typeId”

which is obvious, because typeId field is in class A not B. 这很明显,因为typeId字段在类A中而不在类B中。

Assuming that your JSON documents are like: 假设您的JSON文档如下:

{
  "type": "foo",
  "data": {
    "someCommonProperty": "common property",
    "fooProperty": "foo specific property"
  }
}
{
  "type": "bar",
  "data": {
    "someCommonProperty": "common property",
    "barProperty": "bar specific property"
  }
}

You can use: 您可以使用:

public class Wrapper {

    private String type;

    @JsonTypeInfo(use = Id.NAME, property = "type", include = As.EXTERNAL_PROPERTY)
    @JsonSubTypes(value = { 
        @JsonSubTypes.Type(value = Foo.class, name = "foo"),
        @JsonSubTypes.Type(value = Bar.class, name = "bar") 
    })
    private AbstractData data;

    // Getters and setters
}
public abstract class AbstractData {

    private String someCommonProperty;

    // Getters and setters
}
public class Foo extends AbstractData {

    private String fooProperty;

    // Getters and setters
}
public class Bar extends AbstractData {

    private String barProperty;

    // Getters and setters
}

In this approach, @JsonTypeInfo is set to use type as an external property to determine the right class to map the data property. 在这种方法中,将@JsonTypeInfo设置为将type用作外部属性,以确定映射data属性的正确类。 The JSON document can be deserialized as following: JSON文档可以反序列化如下:

ObjectMapper mapper = new ObjectMapper();
Wrapper wrapper = mapper.readValue(json, Wrapper.class);  

I had the same serialization issue once and I made an implementation like this. 我曾经遇到过同样的序列化问题,并且实现了这样的实现。 see the code below. 请参阅下面的代码。

    protected Entity serialize(Object entity) throws Exception {
    try {
        if ( entity instanceof AbstractProcessRequest ) {
            AbstractProcessRequest request = (AbstractProcessRequest) entity;
            String value = mapper.writeValueAsString(request.prepareJSONRequest());
            logger.info("Telesales String json request " + value);
            return new Entity(value, UTF_8);
        } else {
            String value = mapper.writeValueAsString(entity);
            return new StringEntity(value, UTF_8);
        }
    } catch (Exception e) {
        logger.error("Telesales --> Error occured serializing entity", e);
        throw e;
    }
}

To achieve generic structure an execute method is created in some service class like below. 为了实现通用结构,在某些服务类中创建了execute方法,如下所示。

private <T> T execute(Object entity, Class<T> clazz, HttpRequestBase request, String contentType) throws Exception {

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM