首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >“对于没有InputStream摘要元数据的上传MD5,markSupported()方法必须计算为true。”春季集成AWS

“对于没有InputStream摘要元数据的上传MD5,markSupported()方法必须计算为true。”春季集成AWS
EN

Stack Overflow用户
提问于 2021-01-25 21:33:17
回答 1查看 230关注 0票数 1

更新:春季集成中存在缺陷-AWS-2.3.4

我正在集成SFTP (SftpStreamingMessageSource)作为源,S3作为目标。我有类似的Spring集成配置:

代码语言:javascript
运行
复制
    @Bean
    public S3MessageHandler.UploadMetadataProvider uploadMetadataProvider() {
        return (metadata, message) -> {
            if ( message.getPayload() instanceof DigestInputStream) {
                metadata.setContentType( MediaType.APPLICATION_JSON_VALUE );
                // can not read stream to manually compute MD5
                // metadata.setContentMD5("BLABLA==");
                // this is wrong approach:  metadata.setContentMD5(BinaryUtils.toBase64((((DigestInputStream) message.getPayload()).getMessageDigest().digest()));
            }
        };
    }
    @Bean
    @InboundChannelAdapter(channel = "ftpStream")
    public MessageSource<InputStream> ftpSource(SftpRemoteFileTemplate template) {
        SftpStreamingMessageSource messageSource = new SftpStreamingMessageSource(template);
        messageSource.setRemoteDirectory("foo");
        messageSource.setFilter(new AcceptAllFileListFilter<>());
        messageSource.setMaxFetchSize(1);
        messageSource.setLoggingEnabled(true);
        messageSource.setCountsEnabled(true);
        return messageSource;
    }
...
    @Bean
    @ServiceActivator(inputChannel = "ftpStream")
    public MessageHandler s3MessageHandler(AmazonS3 amazonS3, S3MessageHandler.UploadMetadataProvider uploadMetadataProvider) {
        S3MessageHandler messageHandler = new S3MessageHandler(amazonS3, "bucketName");
        messageHandler.setLoggingEnabled(true);
        messageHandler.setCountsEnabled(true);
        messageHandler.setCommand(S3MessageHandler.Command.UPLOAD);
        messageHandler.setUploadMetadataProvider(uploadMetadataProvider);
        messageHandler.setKeyExpression(new ValueExpression<>("key"));
        return messageHandler;
    }

启动后,我将得到以下错误"For an upload InputStream with no MD5 digest metadata, the markSupported() method must evaluate to true."

这是因为ftpSource在没有标记/重置支持的情况下产生InputStream有效负载。我甚至尝试使用InputStream将BufferedInputStream转换为@Transformer,例如:

代码语言:javascript
运行
复制
return new BufferedInputStream((InputStream) message.getPayload());

没有成功,因为我收到了消息"java.io.IOException: Stream“,因为S3MessageHandler:338调用了Md5Utils.md5AsBase64(inputStream) ,它过早地关闭了流。

如何不痛苦地为中的所有消息生成MD5?

我使用的是spring-integration-AWS-2.3.4

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-25 21:59:50

S3MessageHandler会这样做:

代码语言:javascript
运行
复制
if (payload instanceof InputStream) {
                InputStream inputStream = (InputStream) payload;
                if (metadata.getContentMD5() == null) {
                    Assert.state(inputStream.markSupported(),
                            "For an upload InputStream with no MD5 digest metadata, "
                                    + "the markSupported() method must evaluate to true.");
                    String contentMd5 = Md5Utils.md5AsBase64(inputStream);
                    metadata.setContentMD5(contentMd5);
                    inputStream.reset();
                }
                putObjectRequest = new PutObjectRequest(bucketName, key, inputStream, metadata);
            }

在那里,Md5Utils.md5AsBase64()最终关闭了一个InputStream --对我们不利。

这是我们这方面的疏忽。请提出一个GH问题,我们会尽快解决。或者你可以自由地做出贡献。

作为一种解决办法,我建议在此S3MessageHandler的前面设置一个转换器,代码如下:

代码语言:javascript
运行
复制
return org.springframework.util.StreamUtils.copyToByteArray(inputStream);

这样,您将有一个byte[]作为S3MessageHandler的有效负载,它将使用不同的分支进行处理:

代码语言:javascript
运行
复制
 else if (payload instanceof byte[]) {
                byte[] payloadBytes = (byte[]) payload;
                InputStream inputStream = new ByteArrayInputStream(payloadBytes);
                if (metadata.getContentMD5() == null) {
                    String contentMd5 = Md5Utils.md5AsBase64(inputStream);
                    metadata.setContentMD5(contentMd5);
                    inputStream.reset();
                }
                if (metadata.getContentLength() == 0) {
                    metadata.setContentLength(payloadBytes.length);
                }
                putObjectRequest = new PutObjectRequest(bucketName, key, inputStream, metadata);
            }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65892759

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档