2013-07-21 11 views
12

Ich möchte eine einfache Dateiupload-Funktionalität mit Spring MVC erstellen.Spring Dateiupload nicht verbindlich an Modellattribut Objekt

Ich habe die multipartResolver an Ort und Stelle und arbeiten:

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

Wenn Hochladen einer Datei diese protokolliert:

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] 

, die mir sagt, dass es im Grunde funktioniert.

Dies ist Teil meiner 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> 

Das ist mein Modell Objektklasse Attribut:

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

Und das ist ein Teil meiner Controller-Methode:

@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(); 
} 

Was passiert ist, dass das ImageUpload-Attribut des Formularobjekts nicht gefüllt ist (null), während alle anderen Form-Eigenschaften es sind.

fand ich, dass es funktioniert, wenn ich dies in der Steuerung verwenden:

@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(); 
} 

So, als @RequestParam Werke MultipartFile zu haben, aber es auf die modelAttribute Objekt des Formulars ist nicht bindend. Ich habe Hunderte von Beispielen im Internet gefunden, die ungefähr dasselbe tun und ich finde den Unterschied nicht.

Ich lerne immer noch Frühling, also könnte ich einen sehr offensichtlichen Punkt vermissen. Ich könnte einfach die zweite Version des Controllers verwenden, aber ich verstehe es nicht, und wie gesagt, ich lerne.

Sollten nicht alle <form:input path="abc"> Eigenschaften innerhalb der <form:form modelAttribute="xyz">...</form:form> an xyz.abc gebunden sein? Es funktioniert so für alle Eigenschaften außer dem Datei-Upload.

Irgendwelche Einsichten? Dank

Antwort

5

fand ich das Problem:

ich in der Steuerung ein Verfahren wie dieses hatte, aber vergessen, die imageUpload Eigenschaft hinzufügen. Sehr blöd und einfach einmal gefunden ..!

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

Dies verhindert, dass der Binder andere Eigenschaften als die angegebenen an das modelAttribute bindet. Sehr wichtige Sicherheitsmaßnahme, um zu verhindern, dass Übeltäter gefährliche Informationen in Ihr System eingeben, wenn Sie nur das validieren, was Sie am Frontend erwarten.

Verwandte Themen