@RequestParam in Spring MVC behandelt optionale Parameter

184

Kann ein Federregler beide Arten von Anforderungen bearbeiten?

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

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

Wenn ich einen einzelnen Controller dieser Art definiere:

 @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 {...}

Die HTTP-Anfrage mit "Logout" wird nicht akzeptiert.

Wenn ich zwei Controller definiere, um jede Anforderung separat zu behandeln, beschwert sich Spring mit der Ausnahme "Es gibt bereits eine 'Controller'-Bean-Methode ... zugeordnet".

luksmir
quelle
2
Lesen Sie diesen Artikel: codeflex.co/…
ybonda

Antworten:

224

Sie müssen geben required = falsefür nameund passwordauch Anforderungsparameter. Das liegt daran, dass, wenn Sie nur den logoutParameter angeben, dieser tatsächlich erwartet nameund passwordauch weiterhin obligatorisch ist.

Es hat funktioniert, als Sie gerade gaben nameund passwordweil logoutes dank required = falsebereits gegebener nicht ein obligatorischer Parameter war logout.

SudoRahul
quelle
167

Ab diesem Spring 4.1.1Zeitpunkt haben Sie jetzt die volle Unterstützung von Java 8 Optional( Originalticket) ). In Ihrem Beispiel werden beide Anforderungen über Ihren einzelnen Mapping-Endpunkt required=falsegesendet, solange Sie für Ihre 3 Parameter Abmeldung, Name, Passwort durch Optional ersetzen :

@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
quelle
2
@VibhavChaddha Sie können Folgendes verwenden: if (idOfUser.isPresent ()) {System.out.println ("idOfUser:" + idOfUser.get ()); }
Cassio Seffrin
10
Intellij-Warnung: 'Optional <Long>' wird als Typ für den Parameter 'requestTimelineStart' verwendet. Weniger ... (Strg + F1) Inspektionsinformationen: Meldet alle Verwendungen von java.util.Optional <T>, java.util.OptionalDouble, java. util.OptionalInt, java.util.OptionalLong oder com.google.common.base.Optional als Typ für ein Feld oder einen Parameter. Optional wurde entwickelt, um einen eingeschränkten Mechanismus für Rückgabetypen von Bibliotheksmethoden bereitzustellen, bei denen es eine eindeutige Möglichkeit geben musste, "kein Ergebnis" darzustellen. Die Verwendung eines Felds vom Typ java.util.Optional ist auch problematisch, wenn die Klasse serialisierbar sein muss, was java.util.Optional nicht ist.
PeMa
Dies sollte die neue richtige Antwort mit Java 8 sein, glaube ich.
Java-Addict301
40

Erstellen Sie 2 Methoden, die die Fälle behandeln. Sie können die @RequestMappingAnmerkung anweisen , bestimmte Parameter beim Zuordnen der Anforderung zu berücksichtigen. Auf diese Weise können Sie dies in zwei Methoden aufteilen.

@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
quelle
1
Was passiert, wenn jemand sowohl Abmeldung als auch Name und Passwort an die URL übergibt? Lesen Sie einfach die Dokumentation, es heißt, Sie müssen es !myParam style expressions indicate that the * specified parameter is not supposed to be present in the request.versuchen.
Ringträger
2
Es wird die beste Übereinstimmung finden, es wird wahrscheinlich versuchen, die handleLoginandere zu verwenden, es wird eine Ausnahme geben, die besagt, dass keine Zuordnung gefunden werden kann.
M. Deinum
3
Nur ein Hinweis: Aus Sicherheitsgründen sollte das Abmelden nur POST-Anforderungen akzeptieren, daher sollte es zwei Methoden geben, und es macht keinen Sinn, die URL dann gleich zu halten.
FlasH von Ru