2012-03-26 65 views
4

我是新來的春天,我目前正在努力獲取多部分表單提交/驗證方案,並在視圖中顯示錯誤信息。春季多部分文件上傳表單驗證

這裏有文件,我目前有:

resourceupload.jsp:顯示一個表單,上傳文件的視圖。

<form:form method="post" action="resource/upload" enctype="mutlipart/form-data"> 
<input name="name" type="text"/> 
<input name="file" type="file" /> 
<input type="submit"/> 
<form:errors path="file" cssClass="errors"/> 
</form> 

resourceuploadcontroller.java:處理表單提交,和(unsuccessfuly)嘗試發佈文件驗證錯誤回視圖控制器:

@RequestMapping(method = RequestMethod.POST) 
public String handleFormUpload(@RequestParam("file") MultipartFile file , @RequestParam("name") String name,Object command, Errors validationErrors){ 
..perform some stuff with the file content, checking things in the database, etc... 
.. calling validationErrors.reject("file","the error") everytime something goes wrong... 

return "redirect:upload"; // redirect to the form, that should display the error messages 

現在,很明顯這裏有些不對勁這種方法:

1 /我不得不在validationErrors參數前添加一個虛擬的「command」對象,否則spring會給我一個錯誤。這看起來並不正確。

2 /添加該參數後,重定向不會將錯誤傳遞給視圖。我試圖在控制器的開始使用@SessionAttribute(「文件」),沒有任何運氣。

如果任何人都可以幫助...我有一看註釋@ResponseBody,但似乎並沒有做出與視圖中使用..

回答

3

好像我發現了我的解決辦法擁有。

首先,對我幫助很大的鏈接:http://www.ioncannon.net/programming/975/spring-3-file-upload-example/Spring 3 MVC - form:errors not showing the errors 其表現出良好的技巧來顯示所有的錯誤,使用

<form:errors path="*"/>. 

現在,所有的事情的清單,我改變,使那東西的工作:

1 /使用「rejectValue」而不是「拒絕」。

2 /直接返回視圖而不是重定向。

3 /創建一個CommonsMultipartFile財產

所以,一切的一切是 「UploadItem」 的模式,我的控制器方法成爲

@RequestMapping(method = RequestMethod.POST) 
public String handleFormUpload(@ModelAttribute("uploadItem") UploadItem uploadItem, BindingResult errors){ 
... use errors.rejectValue ... in case of errors (moving everything i could in a UploadItemValidator.validate function) 
return "uploadform" 

希望這有助於。

1

我不認爲這種做法完全擁抱春天,但它的工作原理,是簡單的,並使用一個簡單的HTML表單,並在控制器的一個方法:

HTML文件做後(保存爲JSP或HTML,您的通話)

<html> 
    <head> 
    <title>File Upload Example</title> 
    </head> 
    <body> 
    <form action="save_uploaded_file.html" method="post" enctype="multipart/form-data"> 
     Choose a file to upload to the server: 
     <input name="myFile" type="file"/><br/> 
     <p> 
     <input type="submit"/> 
     <input type="reset"/> 
     </p> 
    </form> 
    </body> 
</html> 
在你的控制器

,有以下方法:

@RequestMapping("/save_uploaded_file") 
public String testUpload(HttpServletRequest request) throws Exception 
{ 
    // get the file from the request 
    MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; 
    MultipartFile multipartFile = multipartRequest.getFile("myFile"); 

    // Note: Make sure this output folder already exists! 
    // The following saves the file to a folder on your hard drive. 
    String outputFilename = "/tmp/uploaded_files/file2.txt"; 
    OutputStream out = new FileOutputStream(outputFilename); 
    IOUtils.copy(multipartFile.getInputStream(), out); 

    return "/save_uploaded_file"; 
} 

要獲得更大的文件要上載的(超過40K),您可能需要指定以下在春天servlet配置....我已經把一些大#在那裏,以確保它的工作,但如果你需要,當然會把「真實」的數字。

<!-- Configure the multipart resolver --> 
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 
    <!-- one of the properties available; the maximum file size in bytes --> 
    <property name="maxUploadSize" value="500000000"/> 
    <property name="maxInMemorySize" value="500000000" /> 
</bean> 

請注意,春季的文件上傳的東西使用Apache Commons FileUpload下蓋。您需要下載並將其包含在您的應用中。這反過來也需要Apache Commons IO,所以你也需要。 (從here報價)

2

這是一個非常簡單的方法來做到這一點:

的formBackingObject:

import org.springframework.web.multipart.commons.CommonsMultipartFile; 

public class FileImport { 

    CommonsMultipartFile importFile; 

    public CommonsMultipartFile getImportFile() { 
     return importFile; 
    } 

    public void setImportFile(CommonsMultipartFile importFile) { 
     this.importFile = importFile; 
    } 
} 

形式:

<sf:form method="POST" modelAttribute="fileImport" enctype="multipart/form-data" action="import"> 
    <table> 
     <spring:hasBindErrors name="fileImport"> 
      <tr> 
       <td colspan="2"> 
        <sf:errors path="importFile" cssClass="error"/> 
       </td> 
      </tr> 
     </spring:hasBindErrors> 
     <tr> 
      <th><label for="importFile">Import Workload:</label></th> 
      <td><input name="importFile" type="file"></td> 
     </tr> 
    </table> 
    <input type="submit" value="Import Application Data"> 
</sf:form> 

最後的ControllerClassMethod:

@RequestMapping(value={"/import"}, method=RequestMethod.POST) 
public String importWorkload(
     FileImport fileImport, BindingResult bindResult, 
     @RequestParam(value="importFile", required=true) MultipartFile importFile){ 
    if(0 == importFile.getSize()){ 
     bindResult.rejectValue("importFile","fileImport.importFile"); 
    } 

    if(bindResult.hasErrors()){ 
     return "admin"; 
    } 
.... 
} 

易Peasy!

@NotNull註釋對文件不起作用的原因是因爲多部分文件在請求對象中從不爲空。但是,它可以有0個字節。您可以花時間實施自定義驗證程序,但爲什麼?

1

在Spring 4,可以實現文件的驗證象下面這樣:

@Component 
public class FileValidator implements Validator { 

    @Override 
    public boolean supports(Class<?> clazz) { 
     return FileModel.class.isAssignableFrom(clazz); 
    } 

    @Override 
    public void validate(Object target, Errors errors) { 
     FileModel fileModel = (FileModel) target; 

     if (fileModel.getFile() != null && fileModel.getFile().isEmpty()){ 
      errors.rejectValue("file", "file.empty"); 
     } 
    } 
} 

然後注入上述驗證到上載控制器,如下圖所示:

@Controller 
@RequestMapping("/") 
public class FileUploadController { 

    @Autowired 
    private FileValidator fileValidator; 

    @ModelAttribute 
    public FileModel fileModel(){ 
     return new FileModel(); 
    } 

    @InitBinder 
    protected void initBinderFileModel(WebDataBinder binder) { 
     binder.setValidator(fileValidator); 
    } 

    @RequestMapping(method = RequestMethod.GET) 
    public String single(){ 
     return "index"; 
    } 

    @RequestMapping(method = RequestMethod.POST) 
    public String handleFormUpload(@Valid FileModel fileModel, 
            BindingResult result, 
            RedirectAttributes redirectMap) throws IOException { 

     if (result.hasErrors()){ 
      return "index"; 
     } 

     MultipartFile file = fileModel.getFile(); 
     InputStream in = file.getInputStream(); 
     File destination = new File("/tmp/" + file.getOriginalFilename()); 
     FileUtils.copyInputStreamToFile(in, destination); 

     redirectMap.addFlashAttribute("filename", file.getOriginalFilename()); 
     return "redirect:success"; 
    } 
} 

此實現幫助您的代碼更清晰且更具可讀性。我從教程中找到它Spring MVC File Upload Validation Example