[英]Jackson Custom deserializer ArrayIndexOutOfBoundsException
[英]Delegating in custom Jackson deserializer
情況如下:我設法讓 Jackson 反序列化以下通用ResponseWrapper<T>
。
static final class ResponseWrapper<T> {
private ResponseData <T> response;
protected static final class ResponseData<T> {
private int status;
private T data;
}
}
使用以下ParameterizedTypeReference
public static <T> ParameterizedTypeReference <ResponseWrapper<T>> typeReferenceOf ( Class<T> tClass ) {
return ParameterizedTypeReference.forType( ParameterizedTypeImpl.make( ResponseWrapper.class, new Type[]{ tClass }, null ) );
}
問題:我需要處理T
的反序列化失敗的情況,因為data
的值不是 object 而是String
。 我需要捕獲異常並將此值分配給ResponseData
中的另一個屬性,例如String errorMessage
。 我的看法是用@JsonDeserialize( using = ResponseDeserializer.class )
注釋response
屬性,但我不知道如何正確實現JsonDeserializer
,以便它將反序列化委托給Jackson的實現,我只是在發生異常時捕獲異常.
對於更多上下文,我使用WebClient
作為 HTTP 客戶端,並使用發生反序列化的交換Function<ClientResponse, Mono<ResponseWrapper<T>>
處理響應。
為了獲得泛型類型,我讓ResponseDeserializer
實現ContextualDeserializer
@Override
public JsonDeserializer<?> createContextual ( DeserializationContext context, BeanProperty property ) throws JsonMappingException {
JavaType wrapperType = property.getType();
JavaType valueType = wrapperType.containedType(0);
return new ResponseDeserializer<>( valueType );
}
這使我可以使用特定的JavaType
創建反序列化器的具體實例。 以下是完整的解決方案:
private static final class ResponseDeserializer<T> extends JsonObjectDeserializer<ResponseWrapper.ResponseData<T>> implements ContextualDeserializer {
private final JavaType javaType;
public ResponseDeserializer ( ) {
this.javaType = null;
}
public ResponseDeserializer ( JavaType javaType ) {
this.javaType = javaType;
}
@Override
public JsonDeserializer<?> createContextual ( DeserializationContext context, BeanProperty property ) throws JsonMappingException {
JavaType wrapperType = property.getType();
JavaType valueType = wrapperType.containedType(0);
return new ResponseDeserializer<>( valueType );
}
@Override
protected ResponseWrapper.ResponseData<T> deserializeObject ( JsonParser jsonParser, DeserializationContext context, ObjectCodec codec, JsonNode tree ) throws IOException {
int status = tree.get( "status" ).asInt();
JsonNode dataNode = tree.get( "data" );
try {
final T data; {
if ( dataNode == null ) {
data = null;
} else {
JsonParser dataParser = dataNode.traverse();
JsonToken token = dataParser.nextToken(); // handle?
data = context.readValue( dataParser, javaType );
}
};
return new ResponseWrapper.ResponseData<T>( status, data );
} catch ( InvalidDefinitionException e ) {
String errorMessage = dataNode.asText();
return new ResponseWrapper.ResponseData<T>( status, errorMessage );
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.