@RequestParam in Spring MVC obsługuje parametry opcjonalne

186

Czy kontroler Spring może obsłużyć oba rodzaje żądań?

1) http://localhost:8080/submit/id/ID123432?logout=true

2) http://localhost:8080/submit/id/ID123432?name=sam&password=543432

Jeśli zdefiniuję pojedynczy kontroler tego rodzaju:

 @RequestMapping (value = "/submit/id/{id}", method = RequestMethod.GET,   
 produces="text/xml")
public String showLoginWindow(@PathVariable("id") String id,
                              @RequestParam(value = "logout", required = false) String logout,
                              @RequestParam("name") String username,
                              @RequestParam("password") String password,
                              @ModelAttribute("submitModel") SubmitModel model,
                              BindingResult errors) throws LoginException {...}

żądanie HTTP z „wylogowaniem” nie jest akceptowane.

Jeśli zdefiniuję dwa kontrolery do obsługi każdego żądania osobno, Spring narzeka z wyjątkiem „Istnieje już metoda fasoli„ Controller ”… zmapowana”.

Luksmir
źródło
2
Przeczytaj ten artykuł: codeflex.co/…
ybonda

Odpowiedzi:

224

Trzeba dać required = falseza namei passwordparametry żądania, jak również. To dlatego, kiedy podać tylko logoutparametr, to faktycznie oczekuje na namei passwordjak są one jeszcze obowiązkowe.

Działało, kiedy właśnie podałeś, namea passwordponieważ logoutnie było to obowiązkowy parametr dzięki required = falsejuż podanemu logout.

SudoRahul
źródło
168

Od tego Spring 4.1.1momentu masz teraz pełną obsługę Java 8 Optional( oryginalny bilet ), dlatego w twoim przykładzie oba żądania będą przechodzić przez jeden punkt końcowy mapowania, o ile zastąpisz required=falseje Opcjonalnym logowaniem, nazwą, hasłem:

@RequestMapping (value = "/submit/id/{id}", method = RequestMethod.GET,   
 produces="text/xml")
public String showLoginWindow(@PathVariable("id") String id,
                              @RequestParam(value = "logout") Optional<String> logout,
                              @RequestParam("name") Optional<String> username,
                              @RequestParam("password") Optional<String> password,
                              @ModelAttribute("submitModel") SubmitModel model,
                              BindingResult errors) throws LoginException {...}
dimitrisli
źródło
2
@VibhavChaddha możesz użyć czegoś takiego: if (idOfUser.isPresent ()) {System.out.println ("idOfUser:" + idOfUser.get ()); }
Cassio Seffrin
10
Ostrzeżenie Intellij: „Opcjonalne <Long>” użyte jako typ parametru „RequestTimelineStart” mniej ... (Strg + F1) Informacje o inspekcji: Zgłasza wszelkie zastosowania java.util.Optional <T>, java.util.OptionalDouble, java. util.OptionalInt, java.util.OptionalLong lub com.google.common.base.Optional jako typ pola lub parametru. Opcjonalny został zaprojektowany w celu zapewnienia ograniczonego mechanizmu dla typów zwracanych metod bibliotecznych, gdzie potrzebny był wyraźny sposób reprezentowania „braku wyniku”. Używanie pola typu java.util.Optional jest również problematyczne, jeśli klasa musi być Serializowalna, czego java.util.Optional nie.
PeMa
Wierzę, że powinna to być nowa poprawna odpowiedź dla Java 8.
java-addict301
40

Utwórz 2 metody obsługujące sprawy. Możesz poinstruować @RequestMappingadnotację, aby uwzględniła określone parametry podczas mapowania żądania. W ten sposób możesz ładnie podzielić to na 2 metody.

@RequestMapping (value="/submit/id/{id}", method=RequestMethod.GET, 
                 produces="text/xml", params={"logout"})
public String handleLogout(@PathVariable("id") String id, 
        @RequestParam("logout") String logout) { ... }

@RequestMapping (value="/submit/id/{id}", method=RequestMethod.GET, 
                 produces="text/xml", params={"name", "password"})
public String handleLogin(@PathVariable("id") String id, @RequestParam("name") 
        String username, @RequestParam("password") String password, 
        @ModelAttribute("submitModel") SubmitModel model, BindingResult errors) 
        throws LoginException {...}
M. Deinum
źródło
1
co się stanie, gdy ktoś przekaże wylogowanie, nazwę i hasło do adresu URL? Wystarczy przeczytać dokumentację, mówi, że muszę !myParam style expressions indicate that the * specified parameter is not supposed to be present in the request.spróbować.
okaziciela pierścienia
2
Znajdzie najlepsze dopasowanie, prawdopodobnie spróbuje użyć handleLogininnego, poda wyjątek stwierdzający, że nie można znaleźć odwzorowania.
M. Deinum,
3
Tylko jedna uwaga: z punktu widzenia bezpieczeństwa wylogowanie powinno akceptować tylko żądania POST, więc powinny istnieć 2 metody i wtedy nie ma sensu utrzymywanie tego samego adresu URL.
FlasH z Ru