我想将多部分文件上传到AWS S3。因此,我必须将其转换。 但是新的File方法需要本地位置才能获取文件。 我可以在当地做。但是在每台机器上运行此代码似乎是一个问题。
请同时找到两种情况。
工作
private File convertMultiPartToFile(MultipartFile multipartFile) throws IOException {
File convFile = new File("C:\\Users\\" + multipartFile.getOriginalFilename());
multipartFile.transferTo(convFile);
return convFile;
}
不起作用
private File convertMultiPartToFile(MultipartFile multipartFile) throws IOException {
File convFile = new File(multipartFile.getOriginalFilename());
multipartFile.transferTo(convFile);
return convFile;
}
Error received :
java.io.FileNotFoundException: newbusiness.jpg (Access is denied)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:270)
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
at java.io.FileOutputStream.<init>(FileOutputStream.java:162)
答案 0 :(得分:1)
您可以使用Spring Content S3。这将隐藏实施细节,因此您无需担心它们。
有一些Spring Boot启动器替代品,但是由于您不使用Spring Boot,因此请将以下依赖项添加到pom.xml
pom.xml
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-s3</artifactId>
<version>0.0.11</version>
</dependency>
添加以下配置,以创建SimpleStorageResourceLoader bean:
@Configuration
@EnableS3Stores
public class S3Config {
@Autowired
private Environment env;
public Region region() {
return Region.getRegion(Regions.fromName(env.getProperty("AWS_REGION")));
}
@Bean
public BasicAWSCredentials basicAWSCredentials() {
return new BasicAWSCredentials(env.getProperty("AWS_ACCESS_KEY_ID"), env.getProperty("AWS_SECRET_KEY"));
}
@Bean
public AmazonS3 client(AWSCredentials awsCredentials) {
AmazonS3Client amazonS3Client = new AmazonS3Client(awsCredentials);
amazonS3Client.setRegion(region());
return amazonS3Client;
}
@Bean
public SimpleStorageResourceLoader simpleStorageResourceLoader(AmazonS3 client) {
return new SimpleStorageResourceLoader(client);
}
}
创建“商店”:
S3Store.java
public interface S3Store extends Store<String> {
}
将此商店自动连接到需要上传资源的位置:
@Autowired
private S3Store store;
WritableResource r = (WritableResource)store.getResource(getId());
InputStream is = // plug your input stream in here
OutputStream os = r.getOutputStream();
IOUtils.copy(is, os);
is.close();
os.close();
启动应用程序时,它将看到对spring-content-s3
和S3Store
接口的依赖性,并为您注入一个实现,因此,您不必担心自己实现此问题。
如果您编写某种Web应用程序或微服务,并且需要REST API,则还可以添加此依赖项:
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-rest</artifactId>
<version>0.0.11</version>
</dependency>
如下更新您的S3Config.java
:
@Configuration
@EnableS3Stores
@Import(RestConfiguration.class)
public class S3Config {
...
如下更新商店:
S3Store.java
@StoreRestResource(path="s3docs")
public interface S3Store extends Store<String> {
}
现在,当您的应用程序启动时,它将看到您的Store
界面,并注入一个@Controller
实现,它将REST请求转发到您的商店。这显然替换了上面的自动装配代码。
然后:
curl -X POST /s3docs/example-doc
会将图像存储在s3中。
curl /s3docs/example-doc
将再次获取它,依此类推。该控制器顺便支持完整的CRUD和视频流。
如果要将此“内容”与JPA实体或类似的东西相关联,则可以使S3Store扩展AssociateStore
或ContentStore
,并且可以使用提供关联的其他方法。
有两个入门指南here。 s3参考指南为here。还有一个教程视频here。编码位大约从1/2开始。
HTH
答案 1 :(得分:0)
Paths
您可以做到
public class UploadStackoverflow {
private String location = "upload-dir";
private Path rootLocation;
public File convertFile(MultipartFile file) throws IOException {
rootLocation = Paths.get(location);
Files.createDirectories(rootLocation);
String filename = StringUtils.cleanPath(file.getOriginalFilename());
InputStream inputStream = file.getInputStream();
Files.copy(inputStream, this.rootLocation.resolve(filename),
StandardCopyOption.REPLACE_EXISTING);
return new File(this.rootLocation.resolve(filename).toAbsolutePath().toString());
}
}
答案 2 :(得分:0)
因为它需要一个临时位置来放置文件。在AWS上部署war之后,以下代码起作用。
private File convertMultiPartToFile(MultipartFile multipartFile) throws IOException {
File convFile = new File(System.getProperty("java.io.tmpdir") + System.getProperty("file.separator") +
multipartFile.getOriginalFilename());
multipartFile.transferTo(convFile);
return convFile;
}