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

时间:2019-06-18 17:07:44

标签: java json spring-boot jackson aws-sdk

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

  

状态”:500,   “错误”:“内部服务器错误”,   “ 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])”,   “ path”:“ / api / s3 / buckets”

我创建了一个名为S3的类,该类具有私有变量。其中之一是名称为bucketList的List类型。此类具有代表性的获取器和设置器,并与这些变量关联。

我还尝试将其添加到application.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;
    }
}

任何对此为何不起作用的想法表示赞赏。

2 个答案:

答案 0 :(得分:1)

Bucket类存在问题。默认情况下,Jackson将所有提供的对象视为POJO -s。每个POJO应该具有getters / setters的列表。如果类没有它们的对象被视为空。如果要序列化此类,可以:

  1. 使用POJO创建额外的getters类,并从原始AWS映射它 这个POJO的类。
  2. 实现并注册此类的序列化程序。
  3. 手动将AWS模型转换为Map-s和List-s并进行序列化。

另请参阅:

答案 1 :(得分:0)

除了上面接受的答案外,解决此问题的另一种方法是提取列表的各个部分,并将它们分别作为单独的列表插入到预先构建的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;