Spring MVC — загрузка файла с валидацией
В прошлой заметке был описан базовый пример загрузки файла с помощью Spring MVC. Здесь будет рассмотрен вариант загрузки файла с реализацией валидации и паттерна Post-Redirect-Get.
В начале короткий код представления:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8"%> <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%> <html> <head> <title>Title</title> </head> <body> <form:form method="post" enctype="multipart/form-data" modelAttribute="uploadedFile" action="uploadFile"> //все атрибуты обязательные <table> <tr> <td>Upload File:</td> <td><input type="file" name="file" /></td> <td style="color: red; font-style: italic;"> <form:errors path="file" /></td> </tr> <tr> <td></td> <td><input type="submit" value="Upload" /></td> <td></td> </tr> </table> </form:form> </body> </html> |
Теперь контроллер:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
@Controller @SessionAttributes("filename") public class FileController { @Autowired private FileValidator fileValidator; //автосвязывание с бином FileValidator private static final Logger logger = LoggerFactory.getLogger(FileController.class); @RequestMapping(value = "/uploadFile", method = RequestMethod.POST) @ResponseBody public ModelAndView uploadFile(@ModelAttribute("uploadedFile") UploadedFile uploadedFile, BindingResult result) {// имена параметров (тут - "uploadedFile") - из формы JSP. ModelAndView modelAndView = new ModelAndView(); String fileName = null; MultipartFile file = uploadedFile.getFile(); fileValidator.validate(uploadedFile, result); if (result.hasErrors()) { modelAndView.setViewName("main"); } else { try { byte[] bytes = file.getBytes(); fileName = file.getOriginalFilename(); String rootPath = "C:\\path\\" File dir = new File(rootPath + File.separator + "loadFiles"); if (!dir.exists()) { dir.mkdirs(); } File loadFile = new File(dir.getAbsolutePath() + File.separator + fileName); BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(loadFile)); stream.write(bytes); stream.flush(); stream.close(); logger.info("uploaded: " + loadFile.getAbsolutePath()); RedirectView redirectView = new RedirectView("fileuploaded"); redirectView.setStatusCode(HttpStatus.FOUND); modelAndView.setView(redirectView); modelAndView.addObject("filename", fileName); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return modelAndView; } @RequestMapping(value = "/fileuploaded", method = RequestMethod.GET) public String fileUploaded() { return "fileuploaded"; } } |
Валидация:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
@Component public class FileValidator implements Validator { @Override public void validate(Object uploadedFile, Errors errors) { UploadedFile file = (UploadedFile) uploadedFile; if (file.getFile().getSize() == 0) { errors.rejectValue("file", "uploadForm.selectFile", "Please select a file!"); } } @Override public boolean supports(Class<?> clazz) { // TODO Auto-generated method stub return false; } } |
Здесь используется собственный класс UploadedFile — обертка для MulipartFile:
1 2 3 4 5 6 7 8 9 10 11 12 |
public class UploadedFile { private MultipartFile file; public MultipartFile getFile() { return file; } public void setFile(MultipartFile file) { this.file = file; } } |
Как это всё работает?
Создана простая форма spring-mvc form:form method="post" enctype="multipart/form-data" modelAttribute="uploadedFile" action="uploadFile" и кнопка для выбора\загрузки файла. Данные отправятся в контроллер в метод ModelAndView uploadFile(@ModelAttribute("uploadedFile") UploadedFile uploadedFile, BindingResult result) .
Здесь получаем MultipartFile из uploadedFile, а так же выполняем метод validate(). В FileValidator идет проверка на 0 размер файла и выдается ошибка с помощью метода rejectValue(). Если ошибка возникла, то переходим на страницу «main», где отображается текст ошибки. В случае нормальной загрузки файла используется редирект с статусом FOUND и перенаправляется на страницу «fileuploaded» уже с методом GET (метод String fileUploaded() ) при этом добавляя объект в сессию(см. аннотацию SessionAtribute в контроллере).
3