2013-09-05 10 views
16

Mi sto insegnando Spring suddividendo le applicazioni di esempio e aggiungendo il codice qua e là per testare le teorie che sviluppo durante la dissezione. Sto ottenendo il seguente messaggio di errore quando si prova un po 'di codice che ho aggiunto a un'applicazione Primavera:Un argomento Errori/BindingResult dovrebbe essere dichiarato immediatamente dopo l'attributo model, @RequestBody o gli argomenti @RequestPart

An Errors/BindingResult argument is expected to be declared immediately after the 
model attribute, the @RequestBody or the @RequestPart arguments to which they apply 

Il metodo a cui il messaggio di errore si riferisce è:

@RequestMapping(value = "/catowners", method = RequestMethod.GET) 
public String findOwnersOfPetType(Integer typeID, BindingResult result, Map<String, Object> model) { 
    // find owners of a specific type of pet 
    typeID = 1;//this is just a placeholder 
    Collection<Owner> results = this.clinicService.findOwnerByPetType(typeID); 
    model.put("selections", results); 
    return "owners/catowners"; 
} 

Questo messaggio di errore è stato innescato quando ho provato a caricare il pattern url/catowners nel browser web. Ho esaminato this page e this posting, ma la spiegazione non sembra chiara.

Qualcuno può mostrarmi come risolvere questo errore e anche spiegare cosa significa?

EDIT:
In base alla risposta del Biju Kunjummen, ho cambiato la sintassi per la seguente:

@RequestMapping(value = "/catowners", method = RequestMethod.GET) 
public String findOwnersOfPetType(@Valid Integer typeID, BindingResult result, Map<String, Object> model) 

ancora sto ottenendo lo stesso messaggio di errore. C'è qualcosa che non capisco?

SECONDO EDIT:

Basato sul commento di Sotirios, ho cambiato il codice di seguito:

@RequestMapping(value = "/catowners", method = RequestMethod.GET) 
public String findOwnersOfPetType(BindingResult result, Map<String, Object> model) { 
    // find owners of a specific type of pet 
    Integer typeID = 1;//this is just a placeholder 
    Collection<Owner> results = this.clinicService.findOwnerByPetType(typeID); 
    model.put("selections", results); 
    return "owners/catowners"; 
} 

ancora sto ottenendo lo stesso messaggio di errore dopo aver detto eclissi a correre come ... eseguito su server di nuovo.

C'è qualcosa che non capisco?

+0

Nono, rimuovere completamente il 'BindingResult'. Cosa ti darebbe anche in quel secondo esempio di modifica? Prenditi un minuto per leggere la sua javadoc per capire a cosa serviva. –

risposta

18

Spring utilizza un'interfaccia chiamata HandlerMethodArgumentResolver per risolvere il parametro nei metodi del gestore e costruire un oggetto da passare come argomento.

Se non ne trova uno, passa null (devo verificarlo).

Il BindingResult è un oggetto risultato che contiene gli errori che possano essere venuti fino convalida di un @ModelAttribute, @Valid, @RequestBody o @RequestPart, in modo da poter utilizzare solo con i parametri che vengono annotati in quanto tale. Ci sono HandlerMethodArgumentResolver per ognuna di quelle annotazioni.

EDIT (risposta al commento)

Il vostro esempio sembra dimostrare che l'utente deve fornire un tipo di animale domestico (come un numero intero). Vorrei cambiare il metodo per

@RequestMapping(value = "/catowners", method = RequestMethod.GET) 
public String findOwnersOfPetType(@RequestParam("type") Integer typeID, Map<String, Object> model) 

e si dovrebbe fare la vostra richiesta (a seconda della configurazione) come

localhost:8080/yourcontext/catowners?type=1 

Anche qui non c'è nulla da validare in modo che non si vuole o bisogno di un BindingResult . Fallirebbe se tu provassi ad aggiungerlo comunque.

+1

Lol, non modificare la mia domanda. Ci sono più regole per 'HandlerMethodArgumentResolver'. Da dove ti aspetti che l'oggetto 'Integer' provenga? Un '@ ModelAttribute' è qualcosa che viene creato dall'oggetto' HttpServletRequest', così come gli altri. –

+0

Stavo cercando di apportare la modifica che ho successivamente apportato al mio post originale sopra. L'overflow dello stack non mi consente di eliminare la modifica accidentale al tuo post. Puoi suggerire un codice reale per risolvere il problema? Queste risposte sembrano esoteriche e il codice effettivo che ho inserito nella mia modifica sopra non rimuove l'errore. – CodeMed

+1

@CodeMed Da dove proviene 'Integer'? È qualcosa che vuoi dal percorso dell'URL, qualche parametro di richiesta, ecc.? –

5

Se si dispone di un parametro di tipo BindingResult, è essenzialmente necessario mantenere eventuali errori quando si associano i parametri di richiesta HTTP a una variabile dichiarata direttamente precedente al parametro del metodo BindingResult.

Quindi tutti questi è accettabile:

@RequestMapping(value = "/catowners", method = RequestMethod.GET) 
public String findOwnersOfPetType(@Valid MyType type, BindingResult result, ...) 


@RequestMapping(value = "/catowners", method = RequestMethod.GET) 
public String findOwnersOfPetType(@ModelAttribute MyType type, BindingResult result, ...) 

@RequestMapping(value = "/catowners", method = RequestMethod.GET) 
public String findOwnersOfPetType(@RequestBody @Valid MyType type, BindingResult result, ...) 
+0

Grazie per aver dedicato del tempo a scrivere una risposta ponderata. Ho apportato una modifica al mio post originale sopra usando quello che pensavo avessi suggerito, ma sta ancora lanciando un messaggio di errore. C'è qualcosa che non capisco? – CodeMed

+2

'@ Valido' con un campo intero non funzionerà. Prova ad usare un tipo contenente invece con un campo intero al suo interno seguito dal parametro 'BindingResult'. –

+0

+1 e grazie. Ora ho risolto il problema utilizzando i vari commenti su questa pagina. – CodeMed

Problemi correlati