2013-09-05 8 views
16

Uczę się Spring, analizując przykładowe aplikacje, a następnie dodając kod tu i tam, aby przetestować teorie, które rozwijam podczas rozbiór. Ja otrzymuję następujący komunikat o błędzie podczas testowania kodu, że dodaje się do stosowania wiosną:Argument Errors/BindingResult powinien zostać zadeklarowany natychmiast po atrybucie modelu, argumentach @RequestBody lub @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 

Metoda do którego odnosi się komunikat o błędzie:

@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"; 
} 

Ten błąd został wywołany kiedy próbował załadować wzorzec URL/cateers w przeglądarce internetowej. Przeczytałem this page i this posting, ale wyjaśnienie nie wydaje się jasne.

Czy ktoś może mi pokazać, jak naprawić ten błąd, a także wyjaśnić, co to znaczy?

EDIT:
podstawie odpowiedzi Biju Kunjummen za zmieniłem składnię do następujących:

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

ja wciąż otrzymuję ten sam komunikat o błędzie. Czy jest coś, czego nie rozumiem?

DRUGA EDYCJA:

podstawie komentarzu Sotirios za zmieniłem kod do następujących:

@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"; 
} 

ja wciąż otrzymuję ten sam komunikat o błędzie po powiedzeniu zaćmienie uruchomić jak uruchomić na ... serwer ponownie.

Czy jest coś, czego nie rozumiem?

+0

Nono, usunąć 'BindingResult' całkowicie. Co dałoby ci to w tym drugim przykładzie edycji? Poświęć chwilę, aby przeczytać jego javadoc, aby zrozumieć, o co mu chodzi. –

Odpowiedz

18

Spring używa interfejsu o nazwie HandlerMethodArgumentResolver, aby rozwiązać parametr w metodach obsługi i skonstruować obiekt, który będzie przekazywany jako argument.

Jeśli go nie znajdzie, przechodzi null (muszę to sprawdzić).

BindingResult jest obiektem wynik, który posiada błędy, które mogą wymyślić walidowaniu @ModelAttribute, @Valid, @RequestBody lub @RequestPart, więc można go używać tylko z parametrów, które są adnotacjami jako takie. Dla każdej z tych adnotacji istnieje HandlerMethodArgumentResolver.

EDIT (odpowiedź na komentarz)

Twój przykład wydaje się wskazywać, że użytkownik powinien dostarczyć typu PET (jako liczba całkowita). Chciałbym zmienić metodę

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

I chcesz uczynić swój wniosek (w zależności od konfiguracji) jak

localhost:8080/yourcontext/catowners?type=1 

też tu nie ma nic do sprawdzania, więc nie chcą lub potrzebują BindingResult . Nie powiodłoby się, gdybyś mimo wszystko spróbował go dodać.

+1

Lol, nie edytuj mojego pytania. Istnieje więcej reguł dla 'HandlerMethodArgumentResolver'. Gdzie spodziewasz się obiektu 'Integer'? "@ ModelAttribute" to coś, co jest budowane z obiektu 'HttpServletRequest', tak samo jak inne. –

+0

Próbowałem dokonać edycji, którą później właśnie napisałem do mojego oryginalnego zamieszczania powyżej. Przepełnienie stosu nie pozwoliłoby mi usunąć przypadkowej zmiany do twojego postu. Czy możesz zasugerować jakiś rzeczywisty kod, aby rozwiązać problem? Te odpowiedzi wydają się być ezoteryczne, a rzeczywisty kod, który wstawiam powyżej, nie usuwa błędu. – CodeMed

+1

@CodeMed Skąd pochodzi nazwa "Integer"? Czy jest to coś, co chcesz ze ścieżki URL, jakiś parametr żądania itp.? –

5

Jeśli masz parametr typu BindingResult, należy zasadniczo zachować wszystkie błędy podczas wiązania parametrów żądania HTTP ze zmienną zadeklarowaną bezpośrednio przed parametrem metody BindingResult.

Więc wszystko to jest do zaakceptowania:

@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

Dziękuję za poświęcenie czasu na napisanie przemyślanej odpowiedzi. Zrobiłem edycję mojego pierwotnego wpisu powyżej, używając sugestii, co sugerowałem, ale wciąż wyświetla się komunikat o błędzie. Czy jest coś, czego nie rozumiem? – CodeMed

+2

'@ Valid' z polem całkowitym nie będzie działać. Spróbuj użyć typu zawierającego zamiast tego z polem całkowitym wewnątrz niego, a następnie parametru 'BindingResult'. –

+0

+1 i dziękuję. Rozwiązałem teraz problem, korzystając z różnych komentarzy na tej stronie. – CodeMed

Powiązane problemy