当前位置: 首页 > 知识库问答 >
问题:

委托自定义Jackson反序列化程序

吕奇
2023-03-14

情况如下:我已经设法让Jackson反序列化以下通用响应器

static final class ResponseWrapper<T> {
    
    private ResponseData <T> response;
    
    protected static final class ResponseData<T> {
    
        private int    status;
        private T      data;
    
    }
    
}

使用以下参数化类型引用

public static <T> ParameterizedTypeReference <ResponseWrapper<T>> typeReferenceOf ( Class<T> tClass ) {
    return ParameterizedTypeReference.forType( ParameterizedTypeImpl.make( ResponseWrapper.class, new Type[]{ tClass }, null ) );
}

问题:我需要处理 T 的去存储化将失败的情况,因为数据的值将不是一个对象,而是一个字符串。我需要捕获异常并将此值分配给响应数据中的另一个属性,例如字符串错误消息。我的看法是用 @JsonDeserialize( using = ResponseDeserializer.class ) 注释响应属性,但我不知道如何正确实现 JsonDeserializer,以便它将反序列化委托给杰克逊的实现,我只是在异常发生时捕获异常。

对于更多的上下文,我使用< code>WebClient作为HTTP客户端,并使用exchange 函数处理响应


共有1个答案

阳博赡
2023-03-14

为了获得泛型类型,我使用了ResponseDeserializer实现ContextualDeserialize

@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 );
           
       }

   }
   
}
 类似资料:
  • 假设我正在为某个类编写自定义序列化,但希望使用默认方法处理其中一个字段。 那要怎么做? 序列化时,我们有。 但反序列化的相应方法是什么? 请注意以下代码: 如何实现MyOuterDeserializer?

  • 我有一个Spring项目,我尝试添加一个自定义反序列化器来反序列化日期属性,具体取决于它们的格式。如果我将其用作Date属性的注释,则效果很好。但是,如果我将反序列化器添加到对象映射器中,当Jackson反序列化日期时,它不会调用。 我尝试这样应用我的自定义反序列化程序: 我不想每次都对Date属性应用注释,我想默认使用此反序列化器。我做错了什么?

  • 我有一个外部服务,我用它来查询一些数据。数据将采用两种格式之一(第一种是“遗留”格式,但需要支持): 或 我想将其映射到以下POJO: 第二种格式的数据(是一个对象)应该像任何其他POJO一样进行反序列化,但给定第一种格式的数据(是字符串),要将其转换为的实例,我想调用

  • 我有下面的JSON,我正试图使用Jackson API反序列化它 我基本上需要一个附件类,它有一个AttachmentFile对象列表,如下所示: 如何使用自定义反序列化器实现这一点? 谢谢

  • 问题内容: 我正在使用Flickr API 。调用该方法时,默认的JSON结果为: 我想将此响应解析为Java对象: JSON属性应按以下方式映射: 不幸的是,我无法找到一种使用Annotations做到这一点的好方法。到目前为止,我的方法是将JSON字符串读入a 并从中获取值。 但是我认为,这是有史以来最不优雅的方式。有没有简单的方法,可以使用注释还是自定义反序列化器? 这对我来说将是很明显的,

  • 我目前正在尝试使用Jackson2.8.4将自定义映射类型序列化和反序列化为JSON。我已经设法基于这个答案实现了序列化,但我正在与反序列化作斗争。下面是一个例子: