Ответ 1
Благодаря некоторым очень полезным комментариям М.Дейнума мне удалось решить эту проблему. Я очистил часть своего оригинального сообщения и публикую это как полный ответ для дальнейшего использования.
Первая ошибка, которую я делал, не была отключена по умолчанию MultipartResolver
, которую предоставляет Spring. Это закончилось тем, что преобразователь обработал HttpServeletRequest
и, таким образом, использовал его, прежде чем мой контроллер мог действовать на него.
Способ отключить его, благодаря М. Дейнуму, был следующим:
multipart.enabled=false
Однако после этого меня ожидала еще одна скрытая ловушка. Как только я отключил многопользовательский преобразователь по умолчанию, я начал получать следующую ошибку при попытке сделать загрузку:
Fri Sep 25 20:23:47 IST 2015
There was an unexpected error (type=Method Not Allowed, status=405).
Request method 'POST' not supported
В моей конфигурации безопасности я включил защиту CSRF. Это потребовало, чтобы я отправил свой запрос POST следующим образом:
<html>
<body>
<form method="POST" enctype="multipart/form-data" action="/upload?${_csrf.parameterName}=${_csrf.token}">
<input type="file" name="file"><br>
<input type="submit" value="Upload">
</form>
</body>
</html>
Я также немного изменил свой контроллер:
@Controller
public class FileUploadController {
@RequestMapping(value="/upload", method=RequestMethod.POST)
public @ResponseBody Response<String> upload(HttpServletRequest request) {
try {
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (!isMultipart) {
// Inform user about invalid request
Response<String> responseObject = new Response<String>(false, "Not a multipart request.", "");
return responseObject;
}
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload();
// Parse the request
FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext()) {
FileItemStream item = iter.next();
String name = item.getFieldName();
InputStream stream = item.openStream();
if (!item.isFormField()) {
String filename = item.getName();
// Process the input stream
OutputStream out = new FileOutputStream(filename);
IOUtils.copy(stream, out);
stream.close();
out.close();
}
}
} catch (FileUploadException e) {
return new Response<String>(false, "File upload error", e.toString());
} catch (IOException e) {
return new Response<String>(false, "Internal server IO error", e.toString());
}
return new Response<String>(true, "Success", "");
}
@RequestMapping(value = "/uploader", method = RequestMethod.GET)
public ModelAndView uploaderPage() {
ModelAndView model = new ModelAndView();
model.setViewName("uploader");
return model;
}
}
где Response - просто простой общий тип ответа, который я использую:
public class Response<T> {
/** Boolean indicating if request succeeded **/
private boolean status;
/** Message indicating error if any **/
private String message;
/** Additional data that is part of this response **/
private T data;
public Response(boolean status, String message, T data) {
this.status = status;
this.message = message;
this.data = data;
}
// Setters and getters
...
}