Spring MVC - Як отримати всі параметри запиту на карті в контролері Spring?


183

Приклад URL-адреси:

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

Я не знаю імен attr1, att2 та attr4.

Я хотів би мати змогу зробити щось подібне (або подібне, не хвилюйтесь, доки я маю доступ до назви парам-карта Map -> value:

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

Як я можу досягти цього за допомогою Spring MVC?

Відповіді:


310

Хоча інші відповіді правильні, це, безумовно, не "Весняний спосіб" безпосередньо використовувати об'єкт HttpServletRequest. Відповідь насправді досить проста, і що б ви очікували, якщо ви ознайомитесь із Spring MVC.

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

41
Якщо ви хочете обробити значення списку, як-от із групи однойменних прапорців, використовуйте: @RequestParam MultiValueMap<String, String>
IcedDante

1
Дякую за це Те ж саме можна зробити і з заголовками: stackoverflow.com/a/19556291/2599745
Rob Worsnop

3
Це працює лише тоді, коли метод запиту GET або POST. Він не працює для методів запиту PUT, DELETE тощо.
Джордж Сіггуроглу

Не забудьте також додати import org.springframework.ui.ModelMap;.
truthadjustr

@typelogic ModelMapне потрібен, щоб отримати всі параметри запиту як мапу; це просто деталь, специфічна для коду ОП.
xlm

34

Редагувати

Було зазначено, що існує ( принаймні, на 3,0 ) чистий механізм Spring MVC, за допомогою якого можна було отримати ці дані. Я не буду деталізувати це тут, оскільки це відповідь іншого користувача. Дивіться відповідь @ AdamGent для детальної інформації, і не забудьте її прийняти.

У документації Spring 3.2 цей механізм згадується як на RequestMappingсторінці JavaDoc, так і на RequestParamсторінці JavaDoc, але попередньо він згадується лише на RequestMappingсторінці. У документації 2.5 цього механізму не згадується.

Це, мабуть, кращий підхід для більшості розробників, оскільки він видаляє (принаймні це) прив'язку до HttpServletRequestоб'єкта, визначеного jar-servlet-api.

/ Редагувати

Ви повинні мати доступ до рядка запитів через request.getQueryString().

На додаток до getQueryString, параметри запиту можна також отримати з request.getParameterMap () у вигляді Карти.


12
Я підозрюю, що хтось спростував цю відповідь лише тому, що getQueryString повертає String, а не Map. Оп шукав карту параметрів. Я додав getParameterMap до вашої відповіді, щоб допомогти зробити її більш правильною :) +1
jmort253

Ні, я прихильнився тому, що це не весняний MVC спосіб це зробити. @RequestParamз радістю візьмемо за Mapпараметр (див. мою відповідь).
Адам Гент

@AdamGent Питання було задано в той момент, коли Spring 3.2 ще не був випущений. Поверніться назад і подивіться на JavaDoc для 3.1, і ви помітите, що немає такої згадки про використання @RequestParamна a Map<String,String>для отримання всіх параметрів рядка запиту. І будь ласка, не відчувайте себе такою огидою щодо відповідей, які ви бачите тут ... вони не такі вже й погані :) static.springsource.org/spring/docs/3.1.x/javadoc-api/org/…
nicholas. hauschild

Я думаю, що він існував у 3.1, але не був JavaDoced. Я не казав, що мене зненацька, але шокований тим, що @RequestParam Map<>шлях був зроблений. Я маю неприємний роздратування тим, що в багатьох сучасних проектах я бачив Spring MVC (весна 3.1 і вище), вони будуть ставити HttpServletRequest і HttpServletResponse на кожен метод. І здається, що молодші розробники використовують StackOverflow та google, а не дивляться на документ. Це ускладнює проект Spring для переходу з серветного api на API Netty. JAX-RS має подібні проблеми зловживань, але в значно меншій мірі.
Адам Гент

І це JavaDoced в 3.1 просто не у всіх потрібних місцях: " Крім того, @RequestParam можна використовувати на параметрі методу Map <String, String> або MultiValueMap <String, String> для отримання доступу до всіх параметрів запиту. " Infact - це все до версії 3.0 (я знав, що використовував її до 3.1). Моє роздратування все ще стоїть на тому, що люди не заважали робити дослідження :)
Адам Гент

14

Об'єкт HttpServletRequest надає карту параметрів. Докладніше див. Request.getParameterMap () .


1
Карта параметрів Get також буде містити дані форми із запиту POST. Якщо користувач не знає ключів у рядку запиту, то як вони зможуть розрізнити між тим, що надійшло з рядка запиту, і тим, що отримано від даних тіла POST?
nicholas.hauschild

Ви кажете мені, що збираєтеся обробити форму форми, але ви не маєте поняття, які фактичні параметри форми?
Кевін

2
У запитанні зазначено, що він не знає, що таке назви параметрів. Також я не знаю, що вони теж є. ;)
nicholas.hauschild

Вибачте, я вважаю це приміщення трохи смішним.
Кевін

11
Це має сенс у додатку, керованому даними. Один, де клієнт може складати шляхи запиту та рядки запиту, а сервер додатків шукає відповідне значення (з будь-якого виду джерел даних), використовуючи ці шляхи та рядки запиту як ключі.
nicholas.hauschild

12

ви можете просто скористатися цим:

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

Це повинно працювати добре


10

Ось простий приклад отримання паролів запитів на карті.

 @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 );
       }

У цьому випадку воно буде пов'язувати значення studentName та studentEmail із змінними імені та електронної пошти відповідно.


8

Використовуйте org.springframework.web.context.request.WebRequestяк параметр у своєму методі контролера, він забезпечує метод getParameterMap(), перевага полягає в тому, що ви не затягуєте свою програму до API сервлетів, WebRequest - приклад об’єкта контексту JavaEE шаблону.


6

Є два інтерфейси

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

Дозволяє отримати доступ до загального параметра запиту, а також request/sessionдоступу до атрибутів без зв’язків із нативним API сервлетів / портлетів .

Наприклад:

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

PS Існують Документи про аргументи, які можна використовувати як параметри контролера.


Дякую, що це працює. Чи можу я запитати, у чому сенс String[]цінності? Я повинен індексувати його до 0, просто щоб отримати значення.
truthadjustr

Тут може бути масив значень на кшталт key=val1,val2або key=val1&key=val2(якщо я правильно пам’ятаю весняну підтримку обох цих позначень), тож ви отримаєте масив з 2 елементами
katoquro

6

Я можу запізнитися на вечірку, але, наскільки я розумію, ти шукаєш щось подібне:

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]);
}

Усі парами будуть зберігатися в jsonObject.


1

Існує принципова різниця між параметрами запиту та параметрами шляху. Виходить так: www.your_domain?queryparam1=1&queryparam2=2- параметри запиту. www.your_domain/path_param1/entity/path_param2- параметри шляху.

Мене здивувало те, що у весняному світі MVC багато людей плутають одне за іншим. Хоча параметри запиту більше схожі на критерії пошуку, парами шляху, швидше за все, однозначно ідентифікують ресурс. Сказавши це, це не означає, що ви не можете мати кілька параметрів шляху у своєму URI, оскільки структура ресурсу може бути вкладена. Наприклад, скажімо, що вам потрібен конкретний автомобільний ресурс конкретної людини:

www.my_site/customer/15/car/2 - шукає другу машину 15-го замовника.

Яким буде корисний примірник для розміщення всіх параметрів шляху на карті? Параметри шляху не мають "ключа", коли ви дивитесь на сам URI, ці ключі всередині карти будуть взяті, наприклад, із вашої анотації @Mapping:

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

З точки зору HTTP / REST перспективні параметри шляху насправді неможливо спроектувати на карту. Вся справа в гнучкості Spring та їхньому бажанні підлаштувати будь-які примхи розробників, на мою думку.

Я б ніколи не використовував карту для параметрів шляху, але це може бути дуже корисно для параметрів запиту.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.