web-dev-qa-db-fra.com

@RequestParam dans Spring MVC traitant les paramètres facultatifs

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

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 "logout" n'est pas acceptée.

Si je définis deux contrôleurs pour traiter chaque demande séparément, Spring se plaint de l'exception "Il existe déjà une méthode de bean 'Contrôleur ... mappée".

160
luksmir

Vous devez également indiquer required = false pour name et password paramètres de demande. En effet, lorsque vous ne fournissez que le paramètre logout, il s’attend réellement à ce que name et password soient également obligatoires.

Cela fonctionnait quand vous veniez de donner name et password parce que logout n'était pas un paramètre obligatoire en raison de required = false déjà indiqué pour logout.

200
SudoRahul

Dans le cadre de Spring 4.1.1, vous bénéficiez désormais de la prise en charge complète de Java 8 Optional ( ticket d'origine ). Par conséquent, dans votre exemple, les deux demandes passeront par votre simple mappage du point final tant que vous remplacez required=false par Facultatif pour la déconnexion de vos 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 {...}
146
dimitrisli

Créez 2 méthodes qui traitent les cas. Vous pouvez demander à l'annotation @RequestMapping de prendre en compte certains paramètres lors du mappage de la demande. De cette façon, vous pouvez bien 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 {...}
35
M. Deinum