저는 많은 구체적인 유형으로 구현할 수있는 OID 인터페이스입니다.
public interface OID {
}
public abstract class OIDBase
implements OID {
private String _id;
}
public class MyOID
extends OIDBase {
public MyOID() {
// default no-args constructor
}
}
public class MyOtherOID
extends OIDBase {
public MyOtherOID() {
// default no-args constructor
}
}
이제 하나는 추상 인터페이스 유형 (OID)을 사용하여 정의되고 다른 하나는 구체적인 유형 (MyOID)을 사용하여 정의 된 두 개의 필드가있는 객체가 있습니다.
public class MyBean {
private OID _absOid;
private MyOID _concreteOid;
public MyBean(final OID absOid,final MyOID concreteOid) {
_absOid = absOid;
_concreteOid = concreteOid;
}
}
jackson을 사용하여 추상 인터페이스 유형 또는 구체적인 유형을 사용하여 정의되었는지 여부에 관계없이 필드를 다르게 직렬화 / 비 직렬화하고 싶습니다.
{
"_absOid": {
"type" : "MyOtherOID",
"id" : "__an_id__"
},
"_concreteOid" : "__another_id___"
}
주의 해당 _absOid
타입 정보 (직렬화 다형)를 포함하여 직렬화 및 _concreteOid
텍스트로 직렬화
이를 위해 OID 인터페이스에 다음과 같이 주석을 달았습니다.
@JsonSubTypes({
@JsonSubTypes.Type(MyOID.class),
@JsonSubTypes.Type(MyOtherOID.class)
})
public interface OID {
}
각 구체적인 유형에 유형 ID를 할당했습니다.
@JsonTypeName("MyOID")
public class MyOID
extends OIDBase {
...
}
@JsonTypeName("MyOtherOID")
public class MyOtherOID
extends OIDBase {
...
}
마지막으로 컨테이너 빈의 추상 정의 필드에 주석이 추가되어 jackson에 유형 정보가 포함됩니다.
public class MyBean {
@JsonTypeInfo(include = JsonTypeInfo.As.PROPERTY,
use = JsonTypeInfo.Id.NAME,
property = "type")
private OID _absOid;
private MyOID _concreteOid;
}
지금까지는 필드가 추상 유형 (OID)을 사용하여 정의되고 필드가 구체적 유형 (MyOID)을 사용하여 정의 된 경우 다르게 직렬화하려면 사용자 지정 직렬화기를 만들어야합니다.
먼저 serializer / deserializer를 사용하도록 구체적인 유형에 주석을 추가합니다.
@JsonTypeName("MyOID")
@JsonSerialize(using=OIDSerializer.class) @JsonDeserialize(using=OIDDeSerializer.class)
public class MyOID
extends OIDBase {
...
}
@JsonTypeName("MyOtherOID")
@JsonSerialize(using=OIDSerializer.class) @JsonDeserialize(using=OIDDeSerializer.class)
public class MyOtherOID
extends OIDBase {
...
}
... 시리얼 라이저 / 디시리얼라이저 코드 :
public static class OIDSerializer
extends JsonSerializer<OID> {
@Override
public void serialize(final OID value,
final JsonGenerator jgen,
final SerializerProvider provider) throws IOException,JsonProcessingException {
// **** used when serializing a concrete type
jgen.writeString(value.toString());
}
@Override
public void serializeWithType(final OID value,
final JsonGenerator jgen,
final SerializerProvider provider,
final TypeSerializer typeSer) throws IOException {
// **** used when serializing a polymorphic type
// guess the type id
WritableTypeId typeId = typeSer.typeId(value,JsonToken.START_OBJECT);
// type prefix
typeSer.writeTypePrefix(jgen,
typeId);
// object
jgen.writeFieldName("id");
jgen.writeString(value.toString());
// type suffix
typeId.wrapperWritten = !jgen.canWriteTypeId();
typeSer.writeTypeSuffix(jgen,
typeId);
}
}
문제가 발생 드 - 직렬화 할 때 json으로 문자열을, 나는 다음과 같은 사용자 정의 디시리얼라이저를 사용했습니다 :
public static class OIDDeSerializer
extends StdDeserializer<OID> {
public MyOIDDeSerializer() {
super(MyOID.class);
}
@Override
public OID deserialize(final JsonParser jp,
final DeserializationContext ctxt) throws IOException,JsonProcessingException {
JsonNode node = jp.getCodec().readTree(jp);
// [1] - Read the id depending on the serialized format
String oidStr = null;
// text node > concrete oid impl serialized as [value]
if (node.getNodeType() == JsonNodeType.STRING) {
oidStr = ((TextNode)node).asText();
}
// oid=value > abstract oid impl serialized as {typeId=[type],oid={value]}
else {
ObjectNode objNode = (ObjectNode)node;
oidStr = objNode.findValue("id").asText();
}
// [2] - Read tye type id
String typeId = objNode.findValue("type").asText()
// PROBLEM!!!!!!
// how get the type from the typeId in order to create the concrete instance
// how access the type resolver????
Class<? extends OID> oidType = RESOLVE TYPE FROM THE ID
return oidType.newInstance();
}
}
그래서 문제 입니다 해결 유형 ID와 유형에 액세스하는 방법을 사용자 정의에 디시리얼라이저 ???
이것을 시도 할 수 있습니다.
AnnotationIntrospector annotationInspector = new JacksonAnnotationIntrospector();
AnnotatedClass annotatedClass = AnnotatedClass.constructWithoutSuperTypes(OID.class,
new ObjectMapper().getSerializationConfig());
List<NamedType> subtypes = annotationInspector.findSubtypes(annotatedClass);
for(NamedType type: subtypes){
if(type.getType().getName().contains(typeId)){
return type.getClass().newInstance();
}
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다