为S3桶添加生命周期规则时遇MalformedXML错误求助
问题描述
想要为S3桶添加一条生命周期规则,在指定天数后删除桶内所有对象,但执行代码时触发MalformedXML错误,疑问是否因目标prefix为空导致?
错误信息
com.amazonaws.services.s3.model.AmazonS3Exception: The XML you provided was not well-formed or did not validate against our published schema (Service: Amazon S3; Status Code: 400; Error Code: MalformedXML; Request ID: 4FR7C3BE85YVEW57; S3 Extended Request ID: fcYaw7u//7o843GjDtGGIQRjYxAMbn7f1iepEIas/Yt5bybM9BjDZ0JbG+SVz/vvE1k/KjaKadQ=; Proxy: null), S3 Extended Request ID: fcYaw7u//7o843GjDtGGIQRjYxAMbn7f1iepEIas/Yt5bybM9BjDZ0JbG+SVz/vvE1k/KjaKadQ=
代码片段
try { BucketLifecycleConfiguration configuration = s3Client.getBucketLifecycleConfiguration(bucketName); if (configuration == null) { BucketLifecycleConfiguration.Rule rule = new BucketLifecycleConfiguration.Rule() .withId("Delete objects in " + expirationInDays + " days") .withFilter(new LifecycleFilter()) .withExpirationInDays(expirationInDays) .withExpiredObjectDeleteMarker(true) .withStatus(BucketLifecycleConfiguration.ENABLED); configuration = new BucketLifecycleConfiguration() .withRules(rule); s3Client.setBucketLifecycleConfiguration(bucketName, configuration); configuration = s3Client.getBucketLifecycleConfiguration(bucketName); } else { log.info("addLifecycleConfiguration: Lifecycle rules found in configuration. Skipping."); } } catch (AmazonClientException ex) { log.error("addLifecycleConfiguration: AmazonClientException. ex={}", ex.getMessage()); }
解决方案
是的,这个错误确实是因为你创建了空的LifecycleFilter导致的。当需要匹配桶内所有对象时,不需要显式设置Filter——S3默认会将规则应用到桶内全部对象。
你当前代码中new LifecycleFilter()未配置任何过滤规则(如Prefix、Tag等),会生成不符合S3 XML schema的无效配置,进而触发MalformedXML错误。
修复方法
直接去掉.withFilter(new LifecycleFilter())这一行即可,修改后的规则代码如下:
BucketLifecycleConfiguration.Rule rule = new BucketLifecycleConfiguration.Rule() .withId("Delete objects in " + expirationInDays + " days") .withExpirationInDays(expirationInDays) .withExpiredObjectDeleteMarker(true) .withStatus(BucketLifecycleConfiguration.ENABLED);
如果确实需要通过Filter匹配所有对象,可配置空Prefix的LifecyclePrefixFilter,而非空的LifecycleFilter:
.withFilter(new LifecycleFilter(new LifecyclePrefixFilter("")))
不过更推荐省略Filter配置,这种方式更简洁且符合S3默认行为。
内容的提问来源于stack exchange,提问作者adityaViswanatham

