2016-11-29 76 views
1

我在春季創建了一個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> 

這是我的控制器

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 

我只有大約3個月到春季,所以任何幫助將不勝感激。

謝謝!

回答

2

您可以將您的html從<input type="file" name="file" />更改爲<input type="file" name="manyfiles" multiple/>,這樣您就可以在表單中選擇多個文件。

在此之後,您只需更改控制器中的post方法,以便獲得一個MultipartFile數組。比你可以迭代這個數組並逐個處理文件。

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

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

編輯:

如果你想要一個asynchonus上傳傳遞byted到上傳方法的標誌是異步

@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)); 
} 
+0

感謝您的快速回復,但您的解決方案讓我選擇多文件。我想讓多個用戶同時上傳文件。目前,如果用戶A正在上傳大文件,則用戶B的上傳會一直等到第一個完成。所以基本上我正在看異步文件上傳。 – bluebrigade23

+0

標記上傳異步 – Daniel