【问题标题】:No serializer found for class in custom Java AWS application在自定义 Java AWS 应用程序中找不到类的序列化程序
【发布时间】: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;
    }
}

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

【问题讨论】:

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


    【解决方案1】:

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

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

    另见:

    【讨论】:

    • 有人可以扩展一下吗?哪一个最简单/推荐?有例子吗?
    • @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;
    
    
    

    【讨论】:

      猜你喜欢
      • 2018-07-28
      • 1970-01-01
      • 2016-08-30
      • 1970-01-01
      • 2016-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-19
      相关资源
      最近更新 更多