2013-02-08 7 views
6

Tworzymy stronę profilu z formularzem, który opcjonalnie ma zdjęcie profilowe. Używamy Wiosna 3,2Wiosenny formularz wysyłania opcjonalny z opcjonalnym plikiem

Oto postać: -

<form:form id="editMember" modelAttribute="memberAjaxEditModel" 
    method="POST" class="form-horizontal" enctype="multipart/form-data" > 
    ... 
    <form:input path="fileData" type="file"/> 
    ... 
</form> 

Oto metoda kontroler: -

@RequestMapping(value = "/{id}", method = RequestMethod.POST) 
public String onEditPost(@PathVariable long id, @Valid @ModelAttribute(MemberAjaxEditModel.KEY) MemberAjaxEditModel model, BindingResult result) throws ServiceRecoverableException { 
.... 
} 

Oto model

public class MemberAjaxEditModel { 

... 
private CommonsMultipartFile fileData; 
... 
} 

Współpracuje jeśli plik jest przesłany w formularzu, ale występują błędy w zmiennej BindingResult, jeśli formularz jest przesłany bez pliku.

Tutaj jest błąd: -

Field error in object 'memberAjaxEditModel' on field 'fileData': rejected value []; codes [typeMismatch.memberAjaxEditModel.fileData,typeMismatch.fileData,typeMismatch.org.springframework.web.multipart.commons.CommonsMultipartFile,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [memberAjaxEditModel.fileData,fileData]; arguments []; default message [fileData]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'org.springframework.web.multipart.commons.CommonsMultipartFile' for property 'fileData'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [org.springframework.web.multipart.commons.CommonsMultipartFile] for property 'fileData': no matching editors or conversion strategy found] 

Odpowiedz

6

Okazuje się, że to jQuery Form plugin który wysyłając pusty łańcuch zamiast co wiosna oczekuje - nie powinna być wysłana.

I rozwiązać problem przy użyciu przed złożeniem aby usunąć wartość fileData jeśli nie została wypełniona tak: -

function beforeSubmit(arr, $form, options){ 
    var fileDataIndex = -1; 

    $.each(arr, function(index, value) { 
      if (value.name == "fileData"){ 
       if (value.value.length == 0){ 
        fileDataIndex = index; 
       } 
      } 
     }); 

    if (fileDataIndex != -1){ 
     arr.remove(fileDataIndex); 
    } 
} 

Mam nadzieję, że to pomaga pewne Googlersom z tym samym problemem.

+2

Dzięki @ Ash, miałem do czynienia z tym samym problemem .. to naprawdę mi pomogło .. Po prostu użyłem arr.splice (fileDataIndex, 1); zamiast arr.remove (fileDataIndex); – Saurabh

+0

To działa również na mnie, ale kiedy używam twojej metody w opcji beforeSubmit, strona jest przeładowywana treścią odpowiedzi (tracę zachowanie AJAX) ... – Labe

+0

Naprawdę nie wiem dlaczego, ale używając modyfikacji Saurabh, mój problem zniknął. Dzięki – Labe

1

użytkowania org.springframework.web.multipart.MultipartFile zamiast CommonsMultipartFile

+0

Co stanie się, gdy usuniesz "@PathVariable long id" z metody onEditPost() (i umieścisz ją w MemberAjaxEditModel)? – Andre

0

Czy masz multipartResolver fasoli zdefiniowane w application-context.xml? Jeśli nie, to to i spróbuj

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 
     <property name="maxUploadSize" value="1000000"/> <!-- File size in bytes. --> 
</bean> 
+0

Dzięki, ale już to miałem (jako klasa @Configuraton). Okazuje się, że była to wtyczka AjaxForm, która wysyłała pusty ciąg zamiast tego, czego oczekuje wiosna - nic do wysłania. –

2

Zobacz także github issue 296:

You can use the iframe option to force the same type of post for both cases:

iframe: true

+0

To zadziałało dla mnie! Dzięki! –

2

spróbuje użyć StringMultipartFileEditor.

@InitBinder 
public void initBinder(WebDataBinder binder) { 
    binder.registerCustomEditor(String.class, new StringMultipartFileEditor()); 
} 
Powiązane problemy