问题
I'm reading this documentation:
http://cloud.spring.io/spring-cloud-aws/spring-cloud-aws.html
on using AWS from a Spring application. I'm particularly interested in S3, so, I set up the application and copied this snippet of code to make sure the set up is working correctly:
Resource resource = this.resourceLoader.getResource("s3://myBucket/rootFile.log");
WritableResource writableResource = (WritableResource) resource;
try (OutputStream outputStream = writableResource.getOutputStream()) {
outputStream.write("test".getBytes());
}
but when I run it, I get this error:
java.lang.ClassCastException: org.springframework.web.context.support.ServletContextResource cannot be cast to org.springframework.core.io.WritableResource
Any ideas what's wrong? is that a setup problem? It doesn't look like to me, but I'm new to this.
回答1:
I had to remove
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
from my dependencies.
When devtools is included, inside the GenericApplicationContext.getResources() method it executes the if block, but without devtools it calls the super.getResource():
public Resource getResource(String location) {
if (this.resourceLoader != null) {
return this.resourceLoader.getResource(location);
}
return super.getResource(location);
}
This will use the s3 protocol handler and give you a different type of Resource that does implement WritableResource.
回答2:
Try declaring/casting Resource class as FileSystemResource instead:
FileSystemResource resource = this.resourceLoader.getResource("s3://myBucket/rootFile.log");
WritableResource writableResource = (WritableResource) resource;
try (OutputStream outputStream = writableResource.getOutputStream()) {
outputStream.write("test".getBytes());
}
回答3:
I have the same issue, turn out that I am using the wrong lib. Try to change dependency from
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-aws</artifactId>
</dependency>
To
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-aws</artifactId>
</dependency>
Also do not forget to add aws config in application.yml, otherwise it won't start.
cloud.aws:
region.static: your-region
credentials:
accessKey: your-key
secretKey: your-secret
Hope this can solve your problem.
回答4:
I've tried to follow the solution proposed by @accresse, but without success. My only way of solving it was declaring a new SimpleStorageProtocolResolver and adding it as a ProtocolResolver to the DefaultResourceLoader. Using Spring Boot 2.1.7 e Spring Cloud Aws 2.1.4.
@Autowired
public void configureResourceLoader(AmazonS3 amazonS3, DefaultResourceLoader resourceLoader) {
SimpleStorageProtocolResolver simpleStorageProtocolResolver = new SimpleStorageProtocolResolver(amazonS3);
// As we are calling it by hand, we must initialize it properly.
simpleStorageProtocolResolver.afterPropertiesSet();
resourceLoader.addProtocolResolver(simpleStorageProtocolResolver);
}
Links to follow:
- https://github.com/spring-cloud/spring-cloud-aws/issues/348
- https://github.com/spring-cloud/spring-cloud-aws/issues/384
- https://github.com/spring-projects/spring-boot/issues/9331
来源:https://stackoverflow.com/questions/47135265/cannot-be-cast-to-org-springframework-core-io-writableresource-on-spring-aws-exa