2011-01-14 6 views
7

Próbuję zmoczyć moje stopy wiosną MVC 3.0, i chociaż mogę go uruchomić, nie mogę wydajnie obsłużyć tego konkretnego scenariusza.Spring MVC 3.0: Jak skutecznie sprawdzić zmienną ścieżki, która jest globalna dla wszystkich mapowań zapytań?

Mam kontroler z który obsługuje "/ {studyName}/Module" prefiks, i wygląda to mniej więcej tak: -

@Controller 
@RequestMapping(value = "/{studyName}/module") 
public class ModuleController { 

    @RequestMapping(...) 
    public ModelAndView getA(@PathVariable String studyName, ...) { 
     if (!validStudy(studyName)) { return bad request; } 
     ... 
    } 

    @RequestMapping(...) 
    public ModelAndView getB(@PathVariable String studyName, ...) { 
     if (!validStudy(studyName)) { return bad request; } 
     ... 
    } 

    @RequestMapping(...) 
    public ModelAndView getC(@PathVariable String studyName, ...) { 
     if (!validStudy(studyName)) { return bad request; } 
     ... 
    } 

    @RequestMapping(...) 
    public ModelAndView getD(@PathVariable String studyName, ...) { 
     if (!validStudy(studyName)) { return bad request; } 
     ... 
    } 
} 

problem z tym kodem jest, mam walidacja studyName rozrzucone nad metodami i prawdopodobnie również w innych metodach kontrolerów. Czy istnieje sposób, w jaki mogę wykonać walidację zmiennej zmiennej studyName w jednym miejscu bez użycia czegoś takiego jak AOP? Jak radzisz sobie z walidacją w ten sposób?

Dzięki.

Odpowiedz

2

Teraz jest trochę trudno zrobić to automatycznie, ale jest to możliwe. Powinieneś użyć dostawcy sprawdzania fasoli (JSR-303), który implementuje dodatek C. Obecnie jest to Apache BeanValidation lub Hibernate Validator 4.2 (który jest w wersji beta).

Dodaj wybraną implementację sprawdzania poprawności fasoli do ścieżki klasy. Będzie to wdrożenie JSR-303, którego używa Spring MVC.

Po drugie, dodaj adnotację do parametru metody za pomocą @Valid i wszelkich adnotacji z ograniczeniami, takich jak @NonNull.

Będzie to wyglądać mniej więcej tak:

public ModelAndView getB(@Valid @NonNull @PathVariable String studyName, ...) { 

który powinien działać. Następnie musisz sprawdzić błędy wiosenne pod kątem jakichkolwiek problemów.

Alternatywnie, jeśli nie wykorzystuje żadnych innych parametrów Wiosna, można zarejestrować walidator z InitBinder tak:

@InitBinder 
public void initBinder(WebDataBinder binder) { 
    binder.setValidator(new StudyNameValidator()); 
} 
+0

+1 do Ciebie. Spojrzałem na @valid, ale w moim przypadku prawdopodobnie muszę utworzyć własną adnotację sprawdzania poprawności, ponieważ muszę sprawdzić, czy nazwa studyName jest zarejestrowana w mojej bazie danych, więc nie mogę używać wbudowanych walidacji z walidatora hibernacji. Jeśli chodzi o wiązanie walidatora, nadal muszę sprawdzić "if (binder.hasErrors()) {do something}" w każdej metodzie kontrolera, co jest dokładnie problemem, z którym obecnie się borykam. Być może jest to jedyne eleganckie rozwiązanie dostępne teraz, ale to naprawdę sprawia, że ​​widzę tę samą kontrolę powtarzaną w każdej metodzie. – limc

+0

Jeśli weryfikacja polega na sprawdzeniu, czy coś istnieje w bazie danych, zakładając, że jest prawdopodobne, po prostu wykonam zapytanie i zarejestruję metodę @ExceptionHandler, aby poradzić sobie z mało prawdopodobnym przypadkiem, w którym nie jest. – GaryF

+1

O ile mogę powiedzieć, nie można jeszcze użyć ważnej adnotacji z PathVariable: https://jira.springsource.org/browse/SPR-6380 –

0

utworzyć prostą klasę walidacji:

public class StudyValidator { 
    public boolean validateStudy(String studyName) { 
     //your validate logic here 
    } 
} 

następnie wstrzyknąć go do ModuleController:

class ModuleController { 
    private StudyValidator sv = new StudyValidator(); //use spring injection to populate. 
    boolean validStudy(String studyName) { 
     return sv.validateStudy(studyName); 
    } 
} 

simples.

+0

Tak, ale nadal muszę wywołać validStudy() w każdej metodzie, co jest dokładnie problemem, z którym teraz borykam się. – limc

+0

Myślę, że wywołanie metody jest znacznie mniejszym złem, niż przejściem przez szaleństwo konfiguracji wiosennej i skonfigurowanie całej zwariowanej klasy, aby zmniejszyć to jedno połączenie liniowe. Dlaczego sprawiamy, że nasze życie jest tak szalenie złożone w imię prostoty? –

+0

Źle zrozumiałem, że celem pytania jest modularyzacja wspólnego kodu do wykorzystania w wielu kontrolerach. Bean Validation powyżej wygląda ładnie! :) – DrUseful

0

Hmmm, nie wiem, czy to będzie działać, ale może być w stanie do @Valid adnotacji jako briefly mentioned in this link on validators.

powodzenia!

+0

Spojrzałem na @Valid, który wydaje się tylko sprawdzać poprawność modelu przy użyciu weryfikatora hibernacji 4 lub mojej niestandardowej klasy weryfikatora. – limc

1

Utwórz klasę StudyName, a następnie zarejestruj WebArgumentResolver dla StudyName i tam przeprowadzaj walidację.

public ModelAndView getA(@PathVariable StudyName studyName){ 
     ... 
    } 

    public class StudyNameResolver implements WebArgumentResolver{ 
     //have resolveArgument method do validation if resolved to a StudyName 
    } 
+0

+1 za poinformowanie mnie o WebArgumentResolver. Spoglądałem na to wcześniej, ale niechętnie używam tego, ponieważ być może będę musiał stworzyć kilka niestandardowych programów tłumaczących dla tego konkretnego projektu. – limc

1

zaczynam używać wiosna 3 i lubię rozwiązania walidacji w ten sposób: publicznego ModelAndView getB (@Valid @NonNull @PathVariable String studyName, ...) {

jednak, gdy pathvariable jest nieprawidłowy (w tym przypadku studyName = null) jak można złapać i wyświetlaczem ten błąd?

Próbowałem użyć wyniku wiązania, ale po prostu nie działa. Ponadto, czy wiesz, jak wyświetlić błąd w jsp?

Dzięki

Powiązane problemy