java - Spring中的多用户文件上传

标签 java spring maven spring-mvc

我正在 Spring 中创建一个 Web 应用程序,它允许多个用户同时上传文件,也可以通过分段上传文件的方式,这样就不存在内存问题,但我当前的代码只允许 1 个用户一次上传文件。在第一个文件完成之前,第二个文件不会启动。我该如何解决这个问题?

这是我的上传表单:

<body>
    <div th:if="${message}">
        <h2 th:text="${message}"></h2>
    </div>
    <div>
        <form method="post" enctype="multipart/form-data" action="/">
            <table>
                <tr><td>File to Upload:</td><td><input type="file" name="file" /></td></tr>
                <div id="drop_zone">Drop files here</div>
                <output id="list"></output>
                <tr><td></td><td><input type="submit" value="Upload" /></td></tr>
            </table>
        </form>
    </div>
    <div>
        <ul>
            <li th:each="file : ${files}">
                <a th:href="${file}" th:text="${file}" />
            </li>
        </ul>
    </div>
</body>

这是我的 Controller

package hello;
import hello.storage.StorageFileNotFoundException;
import hello.storage.StorageService;
import org.apache.tomcat.util.http.fileupload.FileItemStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import java.io.*;
import java.util.stream.Collectors;

@Controller
public class FileUploadController {

private final StorageService storageService;
private static final long serialVersionUID = 3447685998419256747L;
private static final String RESP_SUCCESS = "{\"jsonrpc\" : \"2.0\", \"result\" : \"success\", \"id\" : \"id\"}";
private static final String RESP_ERROR = "{\"jsonrpc\" : \"2.0\", \"error\" : {\"code\": 101, \"message\": \"Failed to open input stream.\"}, \"id\" : \"id\"}";
public static final String JSON = "application/json";
public static final int BUF_SIZE = 2 * 1024;
public static final String FileDir = "C:\\Users\\sshah\\Development\\Uploading Files\\upload-dir\\";

@Autowired
public FileUploadController(StorageService storageService) {
    this.storageService = storageService;
}

@GetMapping("/")
public String listUploadedFiles(Model model) throws IOException {

    model.addAttribute("files", storageService
            .loadAll()
            .map(path ->
                    MvcUriComponentsBuilder
                            .fromMethodName(FileUploadController.class, "serveFile", path.getFileName().toString())
                            .build().toString())
            .collect(Collectors.toList()));

    return "uploadForm";
}

@GetMapping("/files/{filename:.+}")
@ResponseBody
public ResponseEntity<Resource> serveFile(@PathVariable String filename) {

    Resource file = storageService.loadAsResource(filename);
    return ResponseEntity
            .ok()
            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\""+file.getFilename()+"\"")
            .body(file);
}

@PostMapping("/")
public String handleFileUpload(@RequestParam("file") MultipartFile file,
                               RedirectAttributes redirectAttributes) {
  try {
      /*storageService.store(file);*/
      InputStream ip = file.getInputStream();
      saveUploadFile(ip, new File(FileDir + file.getOriginalFilename()));
  }


    catch (Exception e) {
        e.printStackTrace();
    }
    redirectAttributes.addFlashAttribute("message",
            "You successfully uploaded " + file.getOriginalFilename() + "!");

    return "redirect:/";
}

@ExceptionHandler(StorageFileNotFoundException.class)
public ResponseEntity handleStorageFileNotFound(StorageFileNotFoundException exc) {
    return ResponseEntity.notFound().build();
}

private void saveUploadFile(InputStream input, File dst) throws IOException {
    OutputStream out = null;
    try {
        if (dst.exists()) {
            out = new BufferedOutputStream(new FileOutputStream(dst, true),
                    BUF_SIZE);
        } else {
            out = new BufferedOutputStream(new FileOutputStream(dst),
                    BUF_SIZE);
        }
        byte[] buffer = new byte[BUF_SIZE];
        int len = 0;
        while ((len = input.read(buffer)) > 0) {
            out.write(buffer, 0, len);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (null != input) {
            try {
                input.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (null != out) {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
  }
}

Pom.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.springframework</groupId>
<artifactId>gs-uploading-files</artifactId>
<version>0.1.0</version>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.2.RELEASE</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>
</project>

最后是我的Applications.properties 文件:

spring.http.multipart.max-file-size=15000MB
spring.http.multipart.max-request-size=15000MB

我刚进入 Spring 大约 3 个月,所以我们将不胜感激。

谢谢!

最佳答案

您可以从<input type="file" name="file" />更改您的html至<input type="file" name="manyfiles" multiple/>这样您就会得到一个可以选择多个文件的表单。

在此之后,您只需更改 Controller 中的 post 方法,以便获得 MultipartFile 数组。您可以遍历该数组并一一处理文件。

@PostMapping("/")
public String handleFileUpload(@RequestParam("manyfiles") MultipartFile[] files,
                           RedirectAttributes redirectAttributes) {

    for(MultipartFile file : files) {
        //Your upload code
    }
}

编辑:

如果您想要异步上传,请将字节传递给上传方法并将其标记为异步

@Async
public void process(byte[] bs){
    //do some long running processing of bs here
}

@PostMapping("/")
public String handleFileUpload(@RequestParam("file") MultipartFile file,
                           RedirectAttributes redirectAttributes) {
    upload.process(IOUtils.toByteArray(file));
}

关于java - Spring中的多用户文件上传,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40856333/

相关文章:

spring - 在dbcp + spring + hibernate + jdbc中禁用准备好的语句?

java - .jar冲突导致java.lang.RuntimeException : Error starting org. neo4j.kernel.EmbeddedGraphDatabase异常

Java:语句未按顺序执行

java - 可以从TRRS插孔录制声音吗?

java - 启动时启动java进程并在死机时自动重启

java - IntelliJ mac pro 重构 "safe delete"不可用

java - 在 Spring 中配置系统属性

java - 每个实体一个 DAO——如何处理引用?

java - 连接到 Docker 容器中的 H2 数据库

angularjs - 如何配置重定向 Glassfish4 Maven Webapp