Spring загрузка файла не привязка к объекту атрибута модели

Я хочу создать простую функцию загрузки файлов с помощью Spring MVC.

У меня есть multipartResolver на месте и работает:

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  <property name="maxUploadSize" value="10240000"/>
</bean>

При загрузке файла это регистрируется:

DEBUG:[org.springframework.web.multipart.commons.CommonsMultipartResolver]: Found multipart file [imageUpload] of size 29081 bytes with original filename [xyz.jpg], stored at [/home/myuser/workspace/myProject/target/tmp/upload_67f1107c_1b8f_402c_bebd_6cd8a6e4c830_00000032.tmp]

который говорит мне, что он в основном работает.

Это часть моего JSP:

<form:form modelAttribute="placeForm" action="/platz/save" method="post" cssClass="placeForm" enctype="multipart/form-data">
...
        <label for="imageUpload">Upload</label>
        <form:input type="file" path="imageUpload" id="imageUpload" accept="image/*" />
...
</form:form>

Это мой класс объектов класса атрибутов:

public class PlaceEditForm
{
    @Valid
    private Place place = new Place();
    private Map<Integer, PlaceFeature> features;
    private MultipartFile imageUpload;
... getter/setter omitted...
}

И это часть моего метода контроллера:

@RequestMapping(value="/save", method=RequestMethod.POST)
public String savePlace (@Valid @ModelAttribute("placeForm") PlaceEditForm form, BindingResult result)
{
    logger.debug("saveNewPlace");
    logger.debug("Upload: "+form.getImageUpload()); // null
    ...
    return "redirect:/platz/"+place.getPlaceId();
}

Случается, что атрибут imageUpload объекта формы не заполняется (null), тогда как все остальные свойства формы.

Я обнаружил, что он работает, когда я использую это в контроллере:

@RequestMapping(value="/save", method=RequestMethod.POST)
public String savePlace (@Valid @ModelAttribute("placeForm") PlaceEditForm form, BindingResult result, @RequestParam("imageUpload") MultipartFile upload, BindingResult uploadResult)
{
    logger.debug("saveNewPlace");
    logger.debug("Upload: "+upload); // Works!!
    ...
    return "redirect:/platz/"+place.getPlaceId();
}

Итак, использование MultipartFile как @RequestParam работает, но привязка его к объекту формы modelAttribute нет. Я нашел сотни примеров в Интернете, которые делают примерно то же самое, и я не вижу разницы.

Я все еще участвую Spring, поэтому я могу пропустить очень очевидный момент. Я мог бы просто использовать вторую версию контроллера, но я этого не понимаю, и, как я уже сказал, я учусь.

Должны ли все свойства <form:input path="abc"> внутри <form:form modelAttribute="xyz">...</form:form> быть привязаны к xyz.abc? Он работает как это для всех свойств, кроме загрузки файла.

Любые идеи? Благодаря

Ответ 1

Я нашел проблему:

У меня был такой метод в контроллере, но я забыл добавить свойство imageUpload. Очень глупо и легко когда-то найдено..!

@InitBinder
public void initBinder(WebDataBinder binder)
{
    binder.setAllowedFields("place.placeId", "place.name", "place.description", "place.directions", "place.coordinates*", "features*", "tmpFiles*", "removeFiles*");
}

Это предотвращает связывание любых других свойств с атрибутом modelAttribute, чем те, которые указаны. Очень важная мера безопасности, предотвращающая проникновение злоумышленников в опасную информацию в вашу систему, когда вы только подтверждаете, что вы ожидаете от внешнего интерфейса.