Spring MVC - Come ottenere tutti i parametri di richiesta in una mappa nel controller Spring?


183

URL di esempio:

../search/?attr1=value1&attr2=value2&attr4=value4

Non conosco i nomi di attr1, att2 e attr4.

Vorrei essere in grado di fare qualcosa del genere (o simile, non importa, purché abbia accesso alla mappa del nome param della richiesta -> valore:

@RequestMapping(value = "/search/{parameters}", method = RequestMethod.GET)
public void search(HttpServletRequest request, 
@PathVariable Map<String,String> allRequestParams, ModelMap model)
throws Exception {//TODO: implement}

Come posso raggiungere questo obiettivo con Spring MVC?

Risposte:


311

Mentre le altre risposte sono corrette, non è certamente il "modo Spring" di utilizzare direttamente l'oggetto HttpServletRequest. La risposta è in realtà abbastanza semplice e cosa ti aspetteresti se hai familiarità con Spring MVC.

@RequestMapping(value = {"/search/", "/search"}, method = RequestMethod.GET)
public String search(
@RequestParam Map<String,String> allRequestParams, ModelMap model) {
   return "viewName";
}

41
Se stai cercando di elaborare i valori dell'elenco, come da un gruppo di caselle di controllo con lo stesso nome, usa: @RequestParam MultiValueMap<String, String>
IcedDante

1
Grazie per questo. Puoi fare la stessa cosa anche con le intestazioni: stackoverflow.com/a/19556291/2599745
Rob Worsnop

3
Funziona solo quando il metodo di richiesta è GET o POST. Non funziona con i metodi di richiesta PUT, DELETE ecc.
George Siggouroglou,

Non dimenticare di aggiungere import org.springframework.ui.ModelMap;anche.
truthadjustr,

@typelogic ModelMapnon è necessario per ottenere tutti i parametri di richiesta come mappa; questo è semplicemente un dettaglio specifico del codice OP.
XL

34

modificare

È stato sottolineato che esiste ( almeno a partire da 3.0 ) un meccanismo Spring MVC puro mediante il quale si possono ottenere questi dati. Non lo dettaglia qui, in quanto è la risposta di un altro utente. Vedi la risposta di @ AdamGent per i dettagli e non dimenticare di votarla.

Nella documentazione di Spring 3.2 questo meccanismo è menzionato sia nella RequestMappingpagina JavaDoc che nella RequestParampagina JavaDoc, ma in precedenza è menzionato solo nellaRequestMapping pagina. Nella documentazione 2.5 non si fa menzione di questo meccanismo.

Questo è probabilmente l'approccio preferito per la maggior parte degli sviluppatori in quanto rimuove (almeno questo) il legame con l' HttpServletRequestoggetto definito dal vaso servlet-api.

/Modificare

È necessario avere accesso alla stringa di query delle richieste tramite request.getQueryString() .

Oltre a getQueryString, i parametri della query possono anche essere recuperati da request.getParameterMap () come una mappa.


12
Ho il sospetto che qualcuno abbia retrocesso questa risposta solo perché getQueryString restituisce una stringa e non una mappa. L'operazione stava cercando una mappa di parametri. Ho aggiunto getParameterMap alla tua risposta per aiutarti a renderlo più corretto :) +1
jmort253

No, ho effettuato il downvoting perché non è il modo Spring MVC di farlo. @RequestParamprenderò volentieri Mapun parametro (vedi la mia risposta).
Adam Gent,

@AdamGent La domanda è stata posta in un momento in cui Spring 3.2 non era ancora stata rilasciata. Torna indietro e dai un'occhiata a JavaDoc per 3.1 e noterai che non si fa menzione dell'utilizzo @RequestParamsu a Map<String,String>per recuperare tutti i parametri della stringa di query. E per favore, non sentirti così inorridito per le risposte che vedi qui ... non sono poi così male :) static.springsource.org/spring/docs/3.1.x/javadoc-api/org/…
nicholas. hauschild,

Penso che esistesse in 3.1 ma non era JavaDoced. Non ho detto di essere stato detestato ma scioccato dal fatto che la @RequestParam Map<>strada non fosse stata fatta. Ho un leggero fastidio nel fatto che molti progetti moderni che ho visto Spring MVC (primavera 3.1 e successive) metteranno HttpServletRequest e HttpServletResponse su ogni metodo. E sembra che i suoi sviluppatori junior utilizzino StackOverflow e Google invece di guardare il documento. Ciò rende difficile per il progetto Spring passare da API servlet a dire un'API Netty. JAX-RS ha simili problemi di abuso ma in misura molto minore.
Adam Gent,

Ed è JavaDoced in 3.1 semplicemente non nei posti giusti: " Inoltre, @RequestParam può essere utilizzato su un parametro del metodo Map <String, String> o MultiValueMap <String, String> per ottenere l'accesso a tutti i parametri della richiesta. ". Infatti, risale alla versione 3.0 (sapevo di averlo usato prima della 3.1). Il mio fastidio sta ancora nel fatto che la gente non si è preoccupata di fare le ricerche :)
Adam Gent,

14

L'oggetto HttpServletRequest fornisce già una mappa di parametri. Vedi request.getParameterMap () per maggiori dettagli.


1
Ottieni mappa parametri conterrà anche i dati del modulo da una richiesta POST. Se l'utente non conosce le chiavi nella stringa di query, come sarà in grado di distinguere tra cosa proviene dalla stringa di query e cosa proviene dai dati di un corpo POST?
nicholas.hauschild,

Mi stai dicendo che stai per elaborare un post del modulo ma non hai idea di quali siano i parametri del modulo effettivo?
Kevin,

2
La domanda afferma che non sa quali sono i nomi dei parametri. Inoltre, non so nemmeno cosa siano. ;)
nicholas.hauschild il

Mi dispiace, trovo la premessa un po 'ridicola.
Kevin,

11
Ha senso in un'applicazione guidata dai dati. Uno in cui il client può creare percorsi di richiesta e stringhe di query e il server delle applicazioni cerca quindi il valore corrispondente (da qualsiasi tipo di origine dati) utilizzando questi percorsi e stringhe di query come chiavi.
nicholas.hauschild,

12

puoi semplicemente usare questo:

Map<String, String[]> parameters = request.getParameterMap();

Dovrebbe funzionare benissimo


10

Ecco il semplice esempio di come ottenere parametri di richiesta in una mappa.

 @RequestMapping(value="submitForm.html", method=RequestMethod.POST)
     public ModelAndView submitForm(@RequestParam Map<String, String> reqParam) 
       {
          String name  = reqParam.get("studentName");
          String email = reqParam.get("studentEmail");

          ModelAndView model = new ModelAndView("AdmissionSuccess");
          model.addObject("msg", "Details submitted by you::
          Name: " + name + ", Email: " + email );
       }

In questo caso, assocerà il valore di studentName e studentEmail rispettivamente con le variabili name e email.


8

Utilizzare org.springframework.web.context.request.WebRequestcome parametro nel metodo del controller, fornisce il metodo getParameterMap(), il vantaggio è che non si restringe l'applicazione all'API Servlet, WebRequest è un esempio di oggetto contesto modello JavaEE.


6

Ci sono due interfacce

  1. org.springframework.web.context.request.WebRequest
  2. org.springframework.web.context.request.NativeWebRequest

Consente l'accesso ai parametri di richiesta generica e l'accesso agli request/sessionattributi, senza vincoli con l'API Servlet / Portlet nativa .

Ex.:

@RequestMapping(value = "/", method = GET)
public List<T> getAll(WebRequest webRequest){
    Map<String, String[]> params = webRequest.getParameterMap();
    //...
}

PS Ci sono documenti su argomenti che possono essere usati come parametri del controller.


Grazie funziona. Posso chiederti, qual è il punto di String[]valore? Devo indicizzarlo a 0 solo per ottenere il valore.
truthadjustr,

Può esserci una matrice di valori come key=val1,val2o key=val1&key=val2(se ricordo bene supportare entrambe queste notazioni) in modo da ottenere una matrice con 2 elementi
katoquro,

6

Potrei essere in ritardo alla festa, ma secondo la mia comprensione, stai cercando qualcosa del genere:

for(String params : Collections.list(httpServletRequest.getParameterNames())) {
    // Whatever you want to do with your map
    // Key : params
    // Value : httpServletRequest.getParameter(params)                
}

2
@SuppressWarnings("unchecked")
Map<String,String[]> requestMapper=request.getParameterMap();
JsonObject jsonObject=new JsonObject();
for(String key:requestMapper.keySet()){
    jsonObject.addProperty(key, requestMapper.get(key)[0]);
}

Tutti i parametri verranno memorizzati jsonObject.


1

Esiste una differenza fondamentale tra i parametri della query e i parametri del percorso. Va così: www.your_domain?queryparam1=1&queryparam2=2- parametri di query. www.your_domain/path_param1/entity/path_param2- parametri del percorso.

Ciò che ho trovato sorprendente è che nel mondo di Spring MVC molte persone confondono l'una per l'altra. Mentre i parametri della query sono più simili ai criteri per una ricerca, molto probabilmente i parametri del percorso identificheranno in modo univoco una risorsa. Detto questo, ciò non significa che non puoi avere più parametri di percorso nel tuo URI, perché la struttura delle risorse può essere nidificata. Ad esempio, supponiamo che tu abbia bisogno di una risorsa auto specifica di una persona specifica:

www.my_site/customer/15/car/2 - alla ricerca di una seconda auto di un 15 ° cliente.

Quale sarebbe un caso d'uso per mettere tutti i parametri del percorso in una mappa? I parametri del percorso non hanno una "chiave" quando si guarda un URI stesso, quelle chiavi all'interno della mappa verrebbero prese dalla tua annotazione @Mapping, ad esempio:

@GetMapping("/booking/{param1}/{param2}")

Da HTTP / REST i parametri del percorso prospettico non possono essere proiettati su una mappa in realtà. Tutto dipende dalla flessibilità di Spring e dal loro desiderio di soddisfare qualsiasi capriccio degli sviluppatori, secondo me.

Non userei mai una mappa per i parametri del percorso, ma può essere abbastanza utile per i parametri della query.

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.