@RequestParam in Spring MVC che gestisce i parametri opzionali


186

È possibile per un controller Spring gestire entrambi i tipi di richieste?

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

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

Se definisco un singolo controller del tipo:

 @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 richiesta HTTP con "logout" non è accettata.

Se definisco due controller per gestire ciascuna richiesta separatamente, Spring si lamenta con l'eccezione "Esiste già un metodo bean" Controller "... mappato".


2
Leggi questo articolo: codeflex.co/…
ybonda

Risposte:


224

È necessario dare required = falseper namee passwordparametri della richiesta pure. Questo perché, quando si fornisce solo il logoutparametro, in realtà si aspetta namee passwordcosì come sono ancora obbligatori.

Ha funzionato quando hai appena dato namee passwordperché logoutnon era un parametro obbligatorio grazie a required = falsegià dato logout.


168

Da quel momento in Spring 4.1.1poi hai il pieno supporto di Java 8 Optional( ticket originale ), quindi nel tuo esempio entrambe le richieste passeranno attraverso il tuo singolo endpoint di mappatura fintanto che rimpiazzerai required=falsecon Opzionale per il logout, nome, password di 3 parametri:

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

2
@VibhavChaddha puoi usare qualcosa del genere: if (idOfUser.isPresent ()) {System.out.println ("idOfUser:" + idOfUser.get ()); }
Cassio Seffrin,

10
Avviso Intellij: 'Facoltativo <Lungo>' utilizzato come tipo per il parametro 'richiestoTimelineStart' meno ... (Strg + F1) Informazioni sull'ispezione: riporta eventuali usi di java.util.Optional <T>, java.util.OptionalDouble, java. util.OptionalInt, java.util.OptionalLong o com.google.common.base.Optional come tipo per un campo o un parametro. Facoltativo è stato progettato per fornire un meccanismo limitato per i tipi di restituzione del metodo di libreria in cui era necessario un modo chiaro per rappresentare "nessun risultato". L'uso di un campo con tipo java.util.Optional è anche problematico se la classe deve essere serializzabile, mentre java.util.Optional non lo è.
PeMa,

Questa dovrebbe essere la nuova risposta corretta con Java 8 credo.
java-addict301

40

Crea 2 metodi che gestiscono i casi. È possibile indicare @RequestMappingall'annotazione di tenere conto di determinati parametri durante la mappatura della richiesta. In questo modo puoi dividerlo in due modi.

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

1
cosa succederà quando qualcuno passerà all'URL sia il logout, sia il nome e la password? Basta leggere la documentazione, dice che !myParam style expressions indicate that the * specified parameter is not supposed to be present in the request.devo provare.
portatore dell'anello,

2
Troverà la migliore corrispondenza, probabilmente proverà a usare l' handleLoginaltro, dando un'eccezione affermando che non è possibile trovare alcuna mappatura.
M. Deinum,

3
Solo una nota: dal punto di vista della sicurezza il logout dovrebbe accettare solo richieste POST, quindi dovrebbero esserci 2 metodi e non ha senso mantenere lo stesso URL allora.
FlasH da Ru
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.