2017-03-25 6 views
0

JSONファイルの内容によっては、スーパークラスまたはサブクラスのいずれかにデシリアライズする必要があります。ジャンクションでのJSONファイルの多型逆シリアル化

これは、スーパークラスにデシリアライズされるべきで、それはこのようになります場合:

{ 
    "id":"123", 
    "title":"my title", 
    "body":"my body" 
} 

またはサブクラスにそれはこのように見える場合:

{ 
    "id":"123", 
    "title":"my title", 
    "body":"my body", 
    "tags":["tag1", "tag2"] 
} 

だから、唯一の違いは、tags配列です、これは文字列配列に逆シリアル化する必要があります。 しかし、私はJersey(Dropwizard)でPOSTリクエストによってデシリアライズをトリガーすると、{"code":400,"message":"Unable to process JSON"}を返します。

これは、スーパークラスである:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME) 
@JsonSubTypes({ @JsonSubTypes.Type(name = "subdocument", value = SubDocument.class) }) 
public class SuperDocument { 

private String id; 
private String title; 
private String body; 

public SuperDocument() { 

} 

@JsonCreator 
public SuperDocument(@JsonProperty("id") String id, @JsonProperty("title") String title, @JsonProperty("body") String body) { 
    this.id = id; 
    this.title = title; 
    this.body = body; 
} 

@JsonProperty("id") 
public String getId() { 
    return id; 
} 

@JsonProperty("id") 
public void setId(String id) { 
    this.id = id; 
} 

... the other getters and setters ... 
} 

これはサブクラスである:

@JsonTypeName("subdocument") 
public class SubDocument extends SuperDocument { 

private String[] tags; 

public SubDocument() { 

} 

@JsonCreator 
public SubDocument(@JsonProperty("id") String id, @JsonProperty("title") String title, @JsonProperty("body") String body, @JsonProperty("tags") String[] tags) { 
    super(id, title, body); 
    this.tags = tags; 
} 

@JsonProperty("tags") 
public String[] getTags() { 
    return tags; 
} 

@JsonProperty("tags") 
public void setTags(String[] tags) { 
    this.tags = tags; 
} 
} 

あなたは私が間違っているの何を知っていますか?

答えて

1

JsonTypeInfoには、サブクラス/スーパークラスを識別できるプロパティが必要です。その後

{ 
    "id":"123", 
    "title":"my title", 
    "body":"my body", 
    "type":"superdocument" 
} 

{ 
    "id":"123", 
    "title":"my title", 
    "body":"my body", 
    "tags":["tag1", "tag2"], 
    "type":"subdocument" 
} 

以下に示すようにSuperDocument注釈を変更します。例えばください。

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,property="type") 
@JsonSubTypes({ @JsonSubTypes.Type(name = "subdocument", value = SubDocument.class),@JsonSubTypes.Type(name = "superdocument", value = SuperDocument.class) }) 

public class SuperDocument { 

} 

追加のプロパティ「タイプ」intrduceしたくない場合は、以下に示すように、カスタム型のレゾルバとタイプデシリアライザを記述する必要があります。

@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) 
@JsonTypeResolver(DocumentTypeResolver.class) 
public class SuperDocument { 

} 
+0

追加の識別プロパティの下に示すように

public class DocumentTypeResolver extends StdTypeResolverBuilder { @Override public TypeDeserializer buildTypeDeserializer( final DeserializationConfig config, final JavaType baseType, final Collection<NamedType> subtypes) { return new DocumentDeserializer(baseType, null, _typeProperty, _typeIdVisible, _defaultImpl); } } 

カスタムTypeDeserializer

public static class DocumentDeserializer extends AsPropertyTypeDeserializer { public DocumentDeserializer(final JavaType bt, final TypeIdResolver idRes, final String typePropertyName, final boolean typeIdVisible, final Class<?> defaultImpl) { super(bt, idRes, typePropertyName, typeIdVisible, defaultImpl); } public DocumentDeserializer(final AsPropertyTypeDeserializer src, final BeanProperty property) { super(src, property); } @Override public TypeDeserializer forProperty(final BeanProperty prop) { return (prop == _property) ? this : new DocumentDeserializer(this, prop); } @Override public Object deserializeTypedFromObject(final JsonParser jp, final DeserializationContext ctxt) throws IOException { JsonNode node = jp.readValueAsTree(); Class<?> subType =null; JsonNode tags = node.get("tags"); if (tags == null) { subType=SuperDocument.class; } else { subType=SubDocument.class; } JavaType type = SimpleType.construct(subType); JsonParser jsonParser = new TreeTraversingParser(node, jp.getCodec()); if (jsonParser.getCurrentToken() == null) { jsonParser.nextToken(); } JsonDeserializer<Object> deser = ctxt.findContextualValueDeserializer(type, _property); return deser.deserialize(jsonParser, ctxt); } } 

今すぐあなたのSuperDocumentクラスに注釈を付けるトリックは、あなたに感謝でした! – phly

関連する問題