2010-08-26 144 views
20

我一直在將Spring集成到一個應用程序中,並且必須從表單重做文件上傳。 我知道Spring MVC必須提供什麼,以及我需要做什麼來配置我的控制器以便能夠上傳文件。我已經閱讀了足夠的教程來做到這一點,但是這些教程沒有解釋的是正確/最佳實踐方法,以確定如何在實際處理文件後執行/如何完成該操作。下面是一些類似的代碼在Spring MVC的文檔中發現的處理上傳文件的代碼可在
Spring MVC File UploadSpring MVC文件上傳幫助

發現在下面你的例子中可以看到,他們告訴你什麼都做,以獲取該文件,但他們只是說做豆與東西

我已經檢查了許多教程,他們都似乎讓我到這一點,但我真正想知道的是處理該文件的最佳方式。一旦我有一個文件在這一點上,什麼是將這個文件保存到服務器上的目錄最好的方法是什麼?有人可以幫助我嗎?由於

public class FileUploadController extends SimpleFormController { 

protected ModelAndView onSubmit(
    HttpServletRequest request, 
    HttpServletResponse response, 
    Object command, 
    BindException errors) throws ServletException, IOException { 

    // cast the bean 
    FileUploadBean bean = (FileUploadBean) command; 

    let's see if there's content there 
    byte[] file = bean.getFile(); 
    if (file == null) { 
     // hmm, that's strange, the user did not upload anything 
    } 

    //do something with the bean 
    return super.onSubmit(request, response, command, errors); 
} 
+1

只需簡單地打開輸出流並將字節寫入流。 FileOutputStram fos = new FileOutputStream(「location/on/server/filename」); fos.write(file); fos.close(); – mhshams 2010-08-26 18:00:48

+0

你確實意識到你正在關注Spring 2.0的文檔,對吧?從那以後,事情在春天的世界裏發生了很多變化。我強烈建議使用3.0代替,你會發現許多事情更容易,包括文件上傳。 – skaffman 2010-08-26 18:48:42

+0

我已經閱讀了Spring 3.0的文檔以及有關使用多部分表單的文檔,並且多部分處理的文檔與2.0文檔幾乎完全相同。 – TheJediCowboy 2010-08-26 20:18:09

回答

20

這是我喜歡做的同時上傳。我認爲讓春天來處理文件保存是最好的方法。 Spring使用它的MultipartFile.transferTo(File dest)函數。

import java.io.File; 
import java.io.IOException; 

import javax.servlet.http.HttpServletResponse; 

import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestParam; 
import org.springframework.web.bind.annotation.ResponseBody; 
import org.springframework.web.multipart.MultipartFile; 

@Controller 
@RequestMapping("/upload") 
public class UploadController { 

    @ResponseBody 
    @RequestMapping(value = "/save") 
    public String handleUpload(
      @RequestParam(value = "file", required = false) MultipartFile multipartFile, 
      HttpServletResponse httpServletResponse) { 

     String orgName = multipartFile.getOriginalFilename(); 

     String filePath = "/my_uploads/" + orgName; 
     File dest = new File(filePath); 
     try { 
      multipartFile.transferTo(dest); 
     } catch (IllegalStateException e) { 
      e.printStackTrace(); 
      return "File uploaded failed:" + orgName; 
     } catch (IOException e) { 
      e.printStackTrace(); 
      return "File uploaded failed:" + orgName; 
     } 
     return "File uploaded:" + orgName; 
    } 
} 
+0

要獲取基本路徑,請使用request.getServletContext()。getRealPath(「/」) – Roberto 2016-03-15 23:41:14

+1

@Roberto'getRealPath(「/」)'返回web內容目錄。在那裏保存文件不是個好主意。當應用程序重新部署時,保存/上傳的文件將會丟失。 – 2017-03-14 21:04:09

+0

multipartFile.transferTo(dest);給我IOException。我確信我已經創建了所需的目錄。你有什麼想法可能是什麼原因? – 2017-04-18 14:33:14

2

但什麼都不這些教程的講解是怎樣/什麼是要做真正處理文件正確/最佳實踐方法,一旦你擁有了它

最佳實踐取決於你想要做什麼。通常我使用一些AOP來後期處理上傳的文件。然後你可以使用FileCopyUtils存儲你上傳的文件

@Autowired 
@Qualifier("commandRepository") 
private AbstractRepository<Command, Integer> commandRepository; 

protected ModelAndView onSubmit(...) throws ServletException, IOException { 
    commandRepository.add(command); 
} 

AOP描述如下

@Aspect 
public class UploadedFileAspect { 

    @After("execution(* br.com.ar.CommandRepository*.add(..))") 
    public void storeUploadedFile(JoinPoint joinPoint) { 
     Command command = (Command) joinPoint.getArgs()[0]; 

     byte[] fileAsByte = command.getFile(); 
     if (fileAsByte != null) { 
      try { 
       FileCopyUtils.copy(fileAsByte, new File("<SET_UP_TARGET_FILE_RIGHT_HERE>")); 
      } catch (IOException e) { 
       /** 
        * log errors 
        */ 
      } 
     } 

    } 

不要忘記啓用方面(更新模式到Spring 3.0如果需要的話)放在類路徑aspectjrt.jar和aspectjweaver.jar(<SPRING_HOME>/lib中/ AspectJ的)和

<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:aop="http://www.springframework.org/schema/aop" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
          http://www.springframework.org/schema/aop 
          http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> 
    <aop:aspectj-autoproxy /> 
    <bean class="br.com.ar.aop.UploadedFileAspect"/> 
-1

使用下面的控制器類來處理文件上傳。

@Controller 
public class FileUploadController { 

    @Autowired 
    private FileUploadService uploadService; 

    @RequestMapping(value = "/fileUploader", method = RequestMethod.GET) 
    public String home() { 
    return "fileUploader"; 
    } 

    @RequestMapping(value = "/upload", method = RequestMethod.POST) 
    public @ResponseBody List<UploadedFile> upload(MultipartHttpServletRequest request, HttpServletResponse response) throws IOException { 

    // Getting uploaded files from the request object 
    Map<String, MultipartFile> fileMap = request.getFileMap(); 

    // Maintain a list to send back the files info. to the client side 
    List<UploadedFile> uploadedFiles = new ArrayList<UploadedFile>(); 

    // Iterate through the map 
    for (MultipartFile multipartFile : fileMap.values()) { 

     // Save the file to local disk 
     saveFileToLocalDisk(multipartFile); 

     UploadedFile fileInfo = getUploadedFileInfo(multipartFile); 

     // Save the file info to database 
     fileInfo = saveFileToDatabase(fileInfo); 

     // adding the file info to the list 
     uploadedFiles.add(fileInfo); 
    } 

    return uploadedFiles; 
    } 

    @RequestMapping(value = {"/listFiles"}) 
    public String listBooks(Map<String, Object> map) { 

    map.put("fileList", uploadService.listFiles()); 

    return "listFiles"; 
    } 

    @RequestMapping(value = "/getdata/{fileId}", method = RequestMethod.GET) 
    public void getFile(HttpServletResponse response, @PathVariable Long fileId) { 

    UploadedFile dataFile = uploadService.getFile(fileId); 

    File file = new File(dataFile.getLocation(), dataFile.getName()); 

    try { 
     response.setContentType(dataFile.getType()); 
     response.setHeader("Content-disposition", "attachment; filename=\"" + dataFile.getName() + "\""); 

     FileCopyUtils.copy(FileUtils.readFileToByteArray(file), response.getOutputStream()); 


    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    } 


    private void saveFileToLocalDisk(MultipartFile multipartFile) throws IOException, FileNotFoundException { 

    String outputFileName = getOutputFilename(multipartFile); 

    FileCopyUtils.copy(multipartFile.getBytes(), new FileOutputStream(outputFileName)); 
    } 

    private UploadedFile saveFileToDatabase(UploadedFile uploadedFile) { 
    return uploadService.saveFile(uploadedFile); 
    } 

    private String getOutputFilename(MultipartFile multipartFile) { 
    return getDestinationLocation() + multipartFile.getOriginalFilename(); 
    } 

    private UploadedFile getUploadedFileInfo(MultipartFile multipartFile) throws IOException { 

    UploadedFile fileInfo = new UploadedFile(); 
    fileInfo.setName(multipartFile.getOriginalFilename()); 
    fileInfo.setSize(multipartFile.getSize()); 
    fileInfo.setType(multipartFile.getContentType()); 
    fileInfo.setLocation(getDestinationLocation()); 

    return fileInfo; 
    } 

    private String getDestinationLocation() { 
    return "Drive:/uploaded-files/"; 
    } 
} 
+0

UploadedFile未定義。 – MuffinMan 2015-11-06 21:39:39