JSON 파일의 내용에 따라 슈퍼 클래스 나 서브 클래스로 역 직렬화하고 싶습니다.
다음과 같은 경우 수퍼 클래스로 역 직렬화되어야합니다.
{
"id":"123",
"title":"my title",
"body":"my body"
}
또는 다음과 같은 경우 하위 클래스에 :
{
"id":"123",
"title":"my title",
"body":"my body",
"tags":["tag1", "tag2"]
}
따라서 유일한 차이점은 tags
배열이며 문자열 배열로 역 직렬화되어야합니다. 그러나 POST 요청을 통해 Jersey (Dropwizard)에서 deserialization을 트리거하면 {"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;
}
}
내가 뭘 잘못하고 있는지 알아?
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 {
}
추가 속성 "type"을 유도하지 않으려면 사용자 지정 형식 확인자를 작성하고 아래와 같이 deserializer를 입력해야 할 수 있습니다.
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);
}
}
커스텀 타입
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
아래와 같이 수업에 주석을 답니다.
@JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
@JsonTypeResolver(DocumentTypeResolver.class)
public class SuperDocument {
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다