@RequestParam dans Spring MVC gère les paramètres facultatifs

186

Est-il possible pour un contrôleur Spring de gérer les deux types de requêtes?

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

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

Si je définis un seul contrôleur du genre:

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

la requête HTTP avec "déconnexion" n'est pas acceptée.

Si je définis deux contrôleurs pour gérer chaque requête séparément, Spring se plaint de l'exception "Il existe déjà une méthode bean 'Controller' ... mappée".

Luksmir
la source
2
Lire cet article: codeflex.co
...

Réponses:

224

Vous devez donner required = falsepour nameet passwordparamètres de la requête ainsi. En effet, lorsque vous ne fournissez que le logoutparamètre, il attend en fait nameetpassword aussi bien qu'ils sont toujours obligatoires.

Cela a fonctionné quand vous venez de donner nameet passwordparce que ce logoutn'était pas un paramètre obligatoire grâce à required = falsedéjà donné pour logout.

SudoRahul
la source
168

Dans le cadre de la suite Spring 4.1.1, vous bénéficiez désormais d'un support complet de Java 8 Optional( ticket d'origine ), donc dans votre exemple, les deux requêtes passeront par votre seul point de terminaison de mappage tant que vous remplacez required=falsepar Facultatif pour votre déconnexion 3 paramètres, nom, mot de passe:

@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
la source
2
@VibhavChaddha vous pouvez utiliser quelque chose comme ceci: if (idOfUser.isPresent ()) {System.out.println ("idOfUser:" + idOfUser.get ()); }
Cassio Seffrin
10
Avertissement Intellij: 'Optional <Long>' utilisé comme type pour le paramètre 'requiredTimelineStart' less ... (Strg + F1) Info d'inspection: signale toute utilisation de java.util.Optional <T>, java.util.OptionalDouble, java. util.OptionalInt, java.util.OptionalLong ou com.google.common.base.Optional comme type d'un champ ou d'un paramètre. Optionnel a été conçu pour fournir un mécanisme limité pour les types de retour de méthode de bibliothèque là où il fallait une manière claire de représenter "aucun résultat". L'utilisation d'un champ de type java.util.Optional pose également problème si la classe doit être Serializable, ce qui n'est pas le cas de java.util.Optional.
PeMa
Cela devrait être la nouvelle réponse correcte avec Java 8, je crois.
java-addict301
40

Créez 2 méthodes qui gèrent les cas. Vous pouvez demander à l' @RequestMappingannotation de prendre en compte certains paramètres lors du mappage de la demande. De cette façon, vous pouvez diviser cela en 2 méthodes.

@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
la source
1
que se passe-t-il lorsque quelqu'un passe à la fois la déconnexion, le nom et le mot de passe à l'URL? Lisez simplement la documentation, il !myParam style expressions indicate that the * specified parameter is not supposed to be present in the request.faut essayer.
porteur de l'anneau le
2
Il trouvera la meilleure correspondance, il essaiera probablement d'utiliser handleLoginsinon il donnera une exception indiquant qu'aucun mappage ne peut être trouvé.
M. Deinum
3
Juste une remarque: du point de vue de la sécurité, la déconnexion ne devrait accepter que les requêtes POST, il devrait donc y avoir 2 méthodes et cela n'a aucun sens de garder leur URL la même.
FlasH de Ru