使用Java AWS SDK上传文件时无法计算MD5哈希值。

10

我已经在许多论坛上研究了这个错误,但没有解决我的问题。当我使用亚马逊API上传文件到S3时,会抛出以下异常:

com.amazonaws.SdkClientException: Unable to calculate MD5 hash: teste.txt (O sistema não pode encontrar o arquivo especificado)
at com.amazonaws.services.s3.AmazonS3Client.putObject(AmazonS3Client.java:1622)
at com.uezohub.backend.domain.service.S3ServiceImpl.uploadFile(S3ServiceImpl.java:50)
at com.uezohub.backend.domain.service.ConteudoService.uploadConteudo(ConteudoService.java:32)
at com.uezohub.backend.resources.ConteudoResource.publicaConteudo(ConteudoResource.java:33)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:108)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
Caused by: java.io.FileNotFoundException: teste.txt (O sistema não pode encontrar o arquivo especificado)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(Unknown Source)
at java.io.FileInputStream.<init>(Unknown Source)
at com.amazonaws.util.Md5Utils.computeMD5Hash(Md5Utils.java:97)
at com.amazonaws.util.Md5Utils.md5AsBase64(Md5Utils.java:104)
at com.amazonaws.services.s3.AmazonS3Client.putObject(AmazonS3Client.java:1618)
... 57 more

根据我的进阶课程:

S3Config.class

@Bean
public AmazonS3 s3client() {
BasicAWSCredentials awsCreds = new BasicAWSCredentials(awsId, awsKey);
AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                        .withRegion(Regions.fromName(region))
                        .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
                        .disableChunkedEncoding()
                        .build();


return s3Client;
}

S3Service.java

@Override
public String uploadFile(Conteudo conteudo, MultipartFile multipartFile) {
String keyname = "teste";
try {
    File  file = conveteArquivo(multipartFile);
    s3.putObject(new PutObjectRequest(bucketName, keyname, file));
    logger.info("======================= Upload File - Done! ============================");
}  catch (AmazonServiceException e) {
    logger.info("Exceção da AmazonSeviceException em requisições PUT, devido:");
    logger.info("Mensagem de erro:         " + e.getMessage());
    logger.info("Código HTTP:              " + e.getStatusCode());
    logger.info("Código de erro da AWS:    " + e.getErrorCode());
    logger.info("Tipo do erro:             " + e.getErrorType());
    logger.info("ID da requisição:         " + e.getRequestId());
} catch (AmazonClientException e) {
    logger.info("Exceção da AmazonClientException");
    logger.info("Mensagem de erro:         " + e.getMessage());
    e.printStackTrace();
} catch (IllegalStateException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}
return linkBucket + keyname;
}

private File conveteArquivo(MultipartFile multipart) throws IllegalStateException, IOException {
    File convFile = new File( multipart.getOriginalFilename());
    multipart.transferTo(convFile);
    return convFile; 
}

控制器

@PostMapping
public ResponseEntity<Conteudo> publicaConteudo(@RequestPart("file") MultipartFile file, @RequestPart String conteudo ) throws JsonParseException, JsonMappingException, IOException {
     Conteudo conteudoConvertido = new ObjectMapper().readValue(conteudo, Conteudo.class);
     Conteudo conteudoArmazenado = conteudoService.uploadConteudo(conteudoConvertido, file);
     return ResponseEntity.ok(conteudoArmazenado);
}

我正在使用Amazon SDK的1.11.106版本。有人知道这个异常的原因吗?我不知道怎么办。

1个回答

9
问题在于写入临时本地文件并读取它以上传到S3。您截断了异常堆栈,但我假设其中包括以下行:
s3.putObject(new PutObjectRequest(bucketName, keyname, file));

不要直接写入临时文件,而是应该使用MultipartFile.getInputStream() / MultipartFile.getSize()方法获取输入流和文件大小,然后通过这个构造函数将它们传递给PutObjectRequest。


我将完整的异常信息放在了代码中。所以我可以这样做:'s3.putObject(new PutObjectRequest(bucketName, keyname, file.getInputStream(), file.getSize()));' - Igor Ramos
getSize应该放在ObjectMetadata中,它是唯一的必填字段。 - user9016329
那使用一个文件对象怎么样?我应该传递什么给构造函数? - BugsForBreakfast

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接