当前位置: 首页 > 面试题库 >

如何通过Jackson和Spring Boot提供自定义解串器

尚棋
2023-03-14
问题内容

我有以下三个应用程序:

项目1举行

  • 业务逻辑(Spring Cloud功能)
  • 接口 IDemoEntity

项目二

  • AWS特定的处理程序
  • IDemoEntity的 一种实现,具有DynamoDB特定的注释
  • 该项目基于Spring Boot

项目3

  • IDemoEntity的 一种实现,带有CosmosDB批注
  • Azure特定的处理程序

项目1的类如下所示:

public interface IDemoEntity {
    String getName();
    void setName(String name);
}

@Component
public class StoreFunction implements Consumer<Message<IDemoEntity>> {

    @Override
    public void accept(Message<IDemoEntity> t) {

        System.out.println("Stored entity " + t.getPayload().getName());
        return;
    }
}

对于项目2,IDemoEntity的实现如下所示:

@DynamoDBTable(tableName = "DemoEntity")
public class DynamoDemoEntity implements IDemoEntity {

    private String name;
    @Override
    @DynamoDBHashKey
    public String getName() {

        return name;
    }

    @Override
    public void setName(String name) {

        this.name = name;
    }    
}

对于项目3项,实施 IDemoEntity 将类似于 DynamoDemoEntity ,但CosmosDB注解。

该结构可能看起来有些复杂,但是其思路如下:

  1. 一次实施业务逻辑和数据模型(在项目1中)(利用Spring Cloud Function)
  2. 仅为每个平台实现一个包装项目(我从项目2中的AWS Lambda开始,但针对Azure的项目3看起来很相似)以及特定于平台的内容(例如实体实现,需要特定于DB的注释)
  3. 使用项目1作为依赖项编译特定于平台的项目(例如,AWS Lambda的项目2)

我已经尝试过了,安装程序基本上可以正常工作。但是,存在一个大问题:

当调用上面的 StoreFunction时 ,Jackson抛出以下异常:

Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `de.margul.awstutorials.springcloudfunction.logic.IDemoEntity` (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
 at [Source: (String)"{"name": "Detlef"}"; line: 1, column: 1]
    at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
    at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1452)
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1028)
    at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:265)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3004)
    at de.margul.awstutorials.springcloudfunction.aws.handler.RestSpringBootApiGatewayRequestHandler.deserializeBody(RestSpringBootApiGatewayRequestHandler.java:57)
    ... 3 more

这是有道理的,因为杰克逊不知道是否IDemoEntity应该反序列化接收到的JSON 到哪个实现。

现在最简单的方法是放置@JsonDeserialize(as = DynamoDemoEntity.class)IDemoEntity

但是,这将破坏我的完整结构:项目1将不包含任何信息,它是与哪个平台特定的项目一起编译的。

有什么想法,我如何提供自定义反序列化器(例如Spring bean),而又不对项目1进行平台特定的修改?


问题答案:

首先,您需要创建DynamoDemoEntityDeserializer如下的自定义:

class DynamoDemoEntityDeserializer extends JsonDeserializer<DynamoDemoEntity> {
    @Override
    public DynamoDemoEntity deserialize(JsonParser p, DeserializationContext ctxt)
                throws IOException, JsonProcessingException {
       // return DynamoDemoEntity instance;
    }
}

然后,您可以创建com.fasterxml.jackson.databind.Module如下所示的bean :

@Bean
public Module dynamoDemoEntityDeserializer() {
    SimpleModule module = new SimpleModule();
    module.addDeserializer(IDemoEntity.class, new DynamoDemoEntityDeserializer());
    return module;
}

任何类型为com.fasterxml.jackson.databind.Module的bean都会自动注册到自动配置的Jackson2ObjectMapperBuilder中,并应用于它创建的任何ObjectMapper实例。当您向应用程序中添加新功能时,这提供了一种用于贡献自定义模块的全局机制。

来源:如何自定义杰克逊对象映射器



 类似资料:
  • 我有以下三个申请: 项目1有效 业务逻辑(Spring Cloud函数) 接口IDemoEntity null null 对于项目3,IDemoEntity的实现看起来与DynamoDemoEntity类似,但带有CosmosDB注释。 结构看起来可能有点复杂,但其思想如下: 一次实现业务逻辑和数据模型(在项目1中)(利用Spring Cloud功能) 只为每个平台实现一个包装器项目(我从proj

  • 问题内容: 想象以下情况: 我想为Foo写一个定制的Jackson解串器。为了做到这一点(例如,为了反序列化类,它具有属性),我需要知道的具体类型,在使用,在反序列化时间(比如我需要知道是在particluar情况下)。 一个人怎么写这样的反序列化器?因为杰克逊使用类型化的集合和地图来做到这一点,所以应该有可能做到这一点。 说明: 似乎有两个部分可以解决问题: 1)获取内部声明的属性类型并使用其反

  • 本文向大家介绍SpringBoot如何通过自定义注解实现权限检查详解,包括了SpringBoot如何通过自定义注解实现权限检查详解的使用技巧和注意事项,需要的朋友参考一下 前言 最近开发了一个接口,完成后准备自测时,却被拦截器拦截了,提示:(AUTH-NO)未能获得有效的请求参数!怎么会这样呢? 于是我全局搜了这个提示语,结果发现它被出现在一个Aspect类当中了,并且把一个 @interface

  • 本文向大家介绍SpringBoot自定义FailureAnalyzer过程解析,包括了SpringBoot自定义FailureAnalyzer过程解析的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了SpringBoot自定义FailureAnalyzer,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 官网说明 1.1 创建自己的 Fa

  • 问题内容: 我在Jackson的自定义解串器中遇到问题。我想访问默认的序列化器以填充要反序列化的对象。填充之后,我将执行一些自定义操作,但首先,我想使用默认的Jackson行为反序列化对象。 这是我目前拥有的代码。 我需要的是一种初始化默认反序列化器的方法,以便在启动特殊逻辑之前可以预先填充POJO。 从自定义反序列化器中调用反序列化时,无论我如何构造序列化器类,似乎都是从当前上下文中调用该方法。

  • 问题内容: 我认为这是由于与客户端计算机建立的连接不安全。 这是由于你正在与HTTP服务器而不是HTTPS服务器进行通信。可能你没有为HTTPS使用正确的端口号。我在Jackson的自定义解串器中遇到问题。我想访问默认的序列化器以填充要反序列化的对象。填充之后,我将执行一些自定义操作,但首先,我想使用默认的Jackson行为反序列化对象。 这是我目前拥有的代码。 我需要的是一种初始化默认反序列化器