在自定义 Java AWS 应用程序中找不到类的序列化程序

Posted

技术标签:

【中文标题】在自定义 Java AWS 应用程序中找不到类的序列化程序【英文标题】:No serializer found for class in custom Java AWS application 【发布时间】:2019-11-01 09:14:56 【问题描述】:

我正在创建一个 Spring 应用程序,其中调用来自 AWS API 的信息并将其转换为 JSON 以供前端应用程序消化和显示。我目前正在尝试返回一个帐户中所有当前 S3 存储桶的列表,但遇到了 JSON 响应为的问题:

状态“:500, "error": "内部服务器错误", "message": "类型定义错误:[简单类型,类 software.amazon.awssdk.services.s3.model.Bucket];嵌套异常是 com.fasterxml.jackson.databind.exc.InvalidDefinitionException:找不到类软件的序列化程序.amazon.awssdk.services.s3.model.Bucket 并且没有发现用于创建 BeanSerializer 的属性(为避免异常,请禁用 SerializationFeature.FAIL_ON_EMPTY_BEANS)(通过参考链:com.landsend.clouddashboard.data.Class.S3[\"bucketList\ "]-java.util.Collections$UnmodifiableRandomAccessList[0])", “路径”:“/api/s3/buckets”

我创建了一个名为 S3 的类,它具有私有变量。其中之一是名为 bucketList 的 List 类型。此类具有代表性的 getter 和 setter 以及与这些变量相关联。

我也尝试将其添加到 applications.properties 文件中:

spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false

这确实导致错误消失,但我最终得到了一个空的 JSON 文件。

控制器类

@RestController
@RequestMapping(value="/api")
public class S3Controller 

    @Autowired
    private S3Service s3Service;

    @RequestMapping(method= RequestMethod.GET, value="/s3/buckets")
    public S3 ListBuckets()
        return s3Service.listBucket();
    

服务类

@Service
public class S3Service 

    private S3Access s3Access;

    @Autowired
    public S3Service(S3Access s3Access)
        this.s3Access = s3Access;
    
    public S3 listBucket()
        //Any Additional business logic would go here
        return s3Access.listBucket();
    

访问类

@Repository
public class S3Access implements S3Repository 

    @Autowired
    private S3 s3Instance;

    private Region region = Region.US_EAST_1;
    private S3Client s3Client = 
                     S3Client.builder().region(region).build();

    @Override
    public S3 listBucket() 
        ListBucketsRequest listBucketsRequest = ListBucketsRequest.builder().build();
        ListBucketsResponse listBucketsResponse = s3Client.listBuckets(listBucketsRequest);
        s3Instance.setBucketList(listBucketsResponse.buckets());
        return s3Instance;
    

S3 构造函数类

@Component
public class S3 
    private String fileName;
    private String bucketName;
    private int bucketSize;
    private List<Bucket> bucketList;

    public List<Bucket> getBucketList() 
        return bucketList;
    

    public void setBucketList(List<Bucket> bucketList) 
        this.bucketList = bucketList;
    

感谢任何关于为什么这不起作用的想法。

【问题讨论】:

【参考方案1】:

问题在于Bucket 类。 Jackson 默认处理所有提供的对象,如POJO-s。每个POJO 都应该有getters/setters 的列表。如果类没有它们,则对象被视为空。如果你想像这样序列化类,你可以:

    使用getters 创建额外的POJO 类并从原始AWS 映射它 给这个POJO上课。 为此类实现和注册序列化程序。 手动将AWS模型转换为Map-s和List-s并序列化它们。

另见:

How to return N1qlQueryResult as the response of REST API for Couchbase databse?

【讨论】:

有人可以扩展一下吗?哪一个最简单/推荐?有例子吗? @MarkHu,这取决于你的情况。创建一个新问题,链接到这个问题,并显示您的代码。最简单/推荐取决于给定的用例。【参考方案2】:

除了上面接受的答案之外,解决此问题的另一种方法是提取列表的各个部分并将它们作为单独的列表插入到预构建的 POJO 中。

在本例中,我将name()creationDate() 函数放入S3 类中各自的列表中。这允许 Jackson 读取 S3 类并获取所需信息,而无需为 Bucket 类构建额外的 POJO。不完全确定哪种方式实际上更清洁或更有效,但这也适用于我正在做的事情。

S3 构造类

@Component
public class S3 
    private ArrayList<String> bucketList;
    private ArrayList<Instant> bucketCreationDate;

    public ArrayList<Instant> getBucketCreationDate() 
        return bucketCreationDate;
    

    public void setBucketCreationDate(ArrayList<Instant> bucketCreationDate) 
        this.bucketCreationDate = bucketCreationDate;
    

    public ArrayList<String> getBucketList() 
        return bucketList;
    

    public void setBucketList(ArrayList<String> bucketList) 
        this.bucketList = bucketList;
    

访问类

@Repository
public class S3Access implements S3Repository 

    @Autowired
    private S3 s3Instance;

    private Region region = Region.US_EAST_1;
    private S3Client s3Client = S3Client.builder().region(region).build();
    private ArrayList <String> bucketNameList = new ArrayList<>();
    private ArrayList <Instant> bucketCreationDate = new ArrayList<>();

    @Override
    public S3 listBucket() 
        ListBucketsRequest listBucketsRequest = ListBucketsRequest.builder().build();
        ListBucketsResponse listBucketsResponse = s3Client.listBuckets(listBucketsRequest);

        // Adding Bucket Names to Array List
        for (int i = 0; i < listBucketsResponse.buckets().size() ; i++) 
            bucketNameList.add(listBucketsResponse.buckets().get(i).name());
        

        // Adding Bucket Creation Dates to Array List
        for (int i = 0; i < listBucketsResponse.buckets().size() ; i++) 
            bucketCreationDate.add(listBucketsResponse.buckets().get(i).creationDate());
        

        // Setting the lists in the S3 Class
        s3Instance.setBucketCreationDate(bucketCreationDate);
        s3Instance.setBucketList(bucketNameList);

        return s3Instance;


【讨论】:

以上是关于在自定义 Java AWS 应用程序中找不到类的序列化程序的主要内容,如果未能解决你的问题,请参考以下文章

ASDF 在自定义目录中找不到包

在自定义组件中找不到 Designintf.dcu

在自定义拦截器中找不到 RealConnection.noNewExchanges() 的错误符号

量角器:by.model 在自定义指令中找不到元素

在自定义类下拉菜单 Xcode 8.3.2 中找不到自定义控制器类

Delphi DLL Project在自定义BPL中找不到单元,除非“Link with Runtime Packages”为True