多部分文件到文件错误

时间:2018-07-02 14:48:05

标签: spring file spring-mvc amazon-s3

我想将多部分文件上传到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)

3 个答案:

答案 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-s3S3Store接口的依赖性,并为您注入一个实现,因此,您不必担心自己实现此问题。

如果您编写某种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

带有multipart / form-data请求的

会将图像存储在s3中。

curl /s3docs/example-doc

将再次获取它,依此类推。该控制器顺便支持完整的CRUD和视频流。

如果要将此“内容”与JPA实体或类似的东西相关联,则可以使S3Store扩展AssociateStoreContentStore,并且可以使用提供关联的其他方法。

有两个入门指南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;
    }