在自定义 Java AWS 应用程序中找不到 class 的序列化程序
No serializer found for class in custom Java AWS application
我正在创建一个 Spring 应用程序,它在其中调用来自 AWS API 的信息并将其转换为 JSON 供前端应用程序消化和显示。我目前正在尝试 return 列出帐户中所有当前 S3 存储桶的列表,但 运行 遇到一个问题,其中 JSON 响应是:
status": 500,
"error": "Internal Server Error",
"message": "Type definition error: [simple type, class software.amazon.awssdk.services.s3.model.Bucket]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class software.amazon.awssdk.services.s3.model.Bucket and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.landsend.clouddashboard.data.Class.S3[\"bucketList\"]-java.util.Collections$UnmodifiableRandomAccessList[0])",
"path": "/api/s3/buckets"
我创建了一个名为 S3 的 class,它具有私有变量。其中之一是名为 bucketList 的列表类型。这个 class 具有代表性的 getter 和 setter 以及与这些变量相关联的。
我也试过将其添加到 applications.properties 文件中:
spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false
这确实导致错误消失,但我最终得到一个空的 JSON 文件。
控制器Class
@RestController
@RequestMapping(value="/api")
public class S3Controller {
@Autowired
private S3Service s3Service;
@RequestMapping(method= RequestMethod.GET, value="/s3/buckets")
public S3 ListBuckets(){
return s3Service.listBucket();
}
}
服务Class
@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();
}
}
访问Class
@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构造函数Class
@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;
}
}
如有任何关于为什么这不起作用的想法,我们将不胜感激。
Bucket class 有问题。 Jackson
默认情况下将所有提供的对象视为 POJO
-s。每个 POJO
应该有 getters
/setters
的列表。如果 class 没有它们,对象将被视为空。如果你想像这样序列化 classes 你可以:
- 使用
getters
创建额外的 POJO
class 并从原始 AWS
映射它
class 到此 POJO
.
- 为此 class 实施并注册序列化程序。
- 手动将
AWS
模型转换为 Map
-s 和 List
-s 并序列化它们。
另请参阅:
- How to return N1qlQueryResult as the response of REST API for Couchbase databse?
除了上面接受的答案之外,解决此问题的另一种方法是提取列表的各个部分并将它们作为分开的、各自的列表插入到预构建的 POJO 中。
在这个例子中,我将 name()
和 creationDate()
函数放在 S3 Class 中它们自己的列表中。这允许 Jackson 读取 S3 Class 并获取所需的信息,而无需为 Bucket
class 构建额外的 POJO。不完全确定哪种方式实际上更清洁或更有效,但这也适用于我正在做的事情。
S3施工Class
@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;
}
}
访问Class
@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;
我正在创建一个 Spring 应用程序,它在其中调用来自 AWS API 的信息并将其转换为 JSON 供前端应用程序消化和显示。我目前正在尝试 return 列出帐户中所有当前 S3 存储桶的列表,但 运行 遇到一个问题,其中 JSON 响应是:
status": 500, "error": "Internal Server Error", "message": "Type definition error: [simple type, class software.amazon.awssdk.services.s3.model.Bucket]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class software.amazon.awssdk.services.s3.model.Bucket and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.landsend.clouddashboard.data.Class.S3[\"bucketList\"]-java.util.Collections$UnmodifiableRandomAccessList[0])", "path": "/api/s3/buckets"
我创建了一个名为 S3 的 class,它具有私有变量。其中之一是名为 bucketList 的列表类型。这个 class 具有代表性的 getter 和 setter 以及与这些变量相关联的。
我也试过将其添加到 applications.properties 文件中:
spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false
这确实导致错误消失,但我最终得到一个空的 JSON 文件。
控制器Class
@RestController
@RequestMapping(value="/api")
public class S3Controller {
@Autowired
private S3Service s3Service;
@RequestMapping(method= RequestMethod.GET, value="/s3/buckets")
public S3 ListBuckets(){
return s3Service.listBucket();
}
}
服务Class
@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();
}
}
访问Class
@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构造函数Class
@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;
}
}
如有任何关于为什么这不起作用的想法,我们将不胜感激。
Bucket class 有问题。 Jackson
默认情况下将所有提供的对象视为 POJO
-s。每个 POJO
应该有 getters
/setters
的列表。如果 class 没有它们,对象将被视为空。如果你想像这样序列化 classes 你可以:
- 使用
getters
创建额外的POJO
class 并从原始AWS
映射它 class 到此POJO
. - 为此 class 实施并注册序列化程序。
- 手动将
AWS
模型转换为Map
-s 和List
-s 并序列化它们。
另请参阅:
- How to return N1qlQueryResult as the response of REST API for Couchbase databse?
除了上面接受的答案之外,解决此问题的另一种方法是提取列表的各个部分并将它们作为分开的、各自的列表插入到预构建的 POJO 中。
在这个例子中,我将 name()
和 creationDate()
函数放在 S3 Class 中它们自己的列表中。这允许 Jackson 读取 S3 Class 并获取所需的信息,而无需为 Bucket
class 构建额外的 POJO。不完全确定哪种方式实际上更清洁或更有效,但这也适用于我正在做的事情。
S3施工Class
@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;
}
}
访问Class
@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;