AWS Step Functions调用Lambda传递PartETag链表时JSON解析错误排查
解决AWS Step Functions中传递PartETag LinkedList的JSON解析问题
我之前也碰到过类似的坑——Step Functions的状态间数据传递完全依赖JSON序列化/反序列化,而AWS SDK自带的PartETag对象直接传递的话,很容易因为序列化后的冗余字段、缺少默认构造器或者私有字段无法被解析等问题报错。下面给你一套可行的解决方案:
1. 先定义一个极简的PartETag数据传输对象(DTO)
PartETag核心就两个有用的属性:eTag和partNumber,我们完全不需要传递整个AWS SDK对象,自己写个轻量DTO就行:
public class PartETagDTO { private String eTag; private Integer partNumber; // 从AWS PartETag转换的构造方法 public PartETagDTO(PartETag partETag) { this.eTag = partETag.getETag(); this.partNumber = partETag.getPartNumber(); } // 空构造方法(JSON序列化必须要有) public PartETagDTO() {} // Getter和Setter方法,JSON序列化需要访问这些字段 public String getETag() { return eTag; } public void setETag(String eTag) { this.eTag = eTag; } public Integer getPartNumber() { return partNumber; } public void setPartNumber(Integer partNumber) { this.partNumber = partNumber; } }
2. 在分段上传的Lambda中转换并传递DTO列表
每次完成一个分段上传后,把生成的PartETag转成PartETagDTO,加入到列表里再返回给Step Functions:
// 假设你已经完成了当前分段上传,拿到了PartETag对象 PartETag currentPartETag = uploadPartResult.getPartETag(); // 从Step Functions的输入中获取已有的DTO列表(第一个分段就初始化空列表) List<PartETagDTO> existingPartDTOs = input.getPartETagDTOList(); if (existingPartDTOs == null) { existingPartDTOs = new ArrayList<>(); } existingPartDTOs.add(new PartETagDTO(currentPartETag)); // 更新输入对象里的列表,返回给Step Functions input.setPartETagDTOList(existingPartDTOs); return input;
3. 在最终合并的Lambda中还原PartETag列表
到了JobFinishHandler里,把传递过来的DTO列表再转回LinkedList<PartETag>,用来调用S3的合并接口:
@Override public ExportJobParameters handleRequest(ExportJobParameters input, Context context) { // 获取Step Functions传递过来的DTO列表 List<PartETagDTO> partETagDTOList = input.getPartETagDTOList(); // 转换成S3需要的LinkedList<PartETag> LinkedList<PartETag> partETagList = new LinkedList<>(); for (PartETagDTO dto : partETagDTOList) { partETagList.add(new PartETag(dto.getPartNumber(), dto.getETag())); } // 调用S3完成分段上传 CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest() .withBucketName(input.getBucketName()) .withKey(input.getKey()) .withUploadId(input.getUploadId()) .withPartETags(partETagList); s3Client.completeMultipartUpload(completeRequest); // 后续的收尾逻辑... return input; }
4. 检查Step Functions的状态配置
确保你的状态机里每个任务的ResultPath配置正确,比如用"ResultPath": "$"让Lambda的输出完全覆盖当前状态的输入,把DTO列表顺利传递到下一个状态:
"UploadPartState": { "Type": "Task", "Resource": "arn:aws:lambda:你的区域:你的账号ID:function:上传分段的Lambda函数", "Next": "CheckAllPartsCompleted", "ResultPath": "$" }
为什么原来的方式会报错?
AWS SDK的PartETag带有很多内部私有字段、没有默认空构造器,而且它的序列化逻辑不是为JSON跨服务传递设计的——Step Functions的JSON解析器无法处理这种复杂的SDK对象,自然就会抛出解析错误。用自定义DTO只保留必要字段,就能完美避开这个问题。
内容的提问来源于stack exchange,提问作者1housand
相关产品推荐
相关产品推荐

