Spring MVC - Как получить все параметры запроса на карте в контроллере Spring?

183

Пример URL:

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

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

Я хотел бы иметь возможность делать что-то подобное (или подобное, все равно, только если у меня есть доступ к имени параметра Map of request -> 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?

MDB
источник

Ответы:

311

Хотя другие ответы верны, это, конечно, не «весенний путь» для непосредственного использования объекта 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>
флажков
1
Спасибо за это. То же самое можно сделать и с заголовками: stackoverflow.com/a/19556291/2599745
Роб Уорсноп
3
Это работает только когда метод запроса GET или POST. Он не работает для методов запроса PUT, DELETE и т. Д.
Джордж Сиггуроглу
Не забудьте также добавить import org.springframework.ui.ModelMap;.
Правда от
@typelogic ModelMapне требуется для получения всех параметров запроса в виде карты; это просто деталь, специфичная для кода OP.
XLM
34

редактировать

Было отмечено, что существует ( по крайней мере, начиная с версии 3.0 ) механизм Spring Spring MVC, с помощью которого можно получить эти данные. Я не буду подробно описывать это здесь, так как это ответ другого пользователя. Подробности смотрите в ответе @ AdamGent , и не забудьте поднять голос.

В документации Spring 3.2 этот механизм упоминается как на RequestMappingстранице JavaDoc, так и на RequestParamстранице JavaDoc, но ранее он упоминается только на RequestMappingстранице. В документации 2.5 нет упоминания об этом механизме.

Это, вероятно, предпочтительный подход для большинства разработчиков, поскольку он удаляет (по крайней мере, это) привязку к HttpServletRequestобъекту, определенному jar-сервлетом-api.

/Редактировать

Вы должны иметь доступ к строке запроса запросов через request.getQueryString().

В дополнение к getQueryString параметры запроса также могут быть получены из request.getParameterMap () в виде Map.

nicholas.hauschild
источник
12
Я подозреваю, что кто-то отклонил этот ответ только потому, что getQueryString возвращает String, а не Map. Оператор искал карту параметров. Я добавил getParameterMap к вашему ответу, чтобы сделать его более правильным :) +1
jmort253
Нет, я понизил голос, потому что это не Spring MVC способ сделать это. @RequestParamс удовольствием приму Mapв качестве параметра (см. мой ответ).
Адам Гент
@AdamGent Вопрос был задан в то время, когда Spring 3.2 еще не был выпущен. Вернитесь назад и посмотрим на JavaDoc для 3.1, и вы заметите , что нет такого упоминания использования @RequestParamна , Map<String,String>чтобы получить все параметры строки запроса. И , пожалуйста, не чувствую себя так вознегодовал над ответами , которые вы видите здесь ... они не что плохо :) static.springsource.org/spring/docs/3.1.x/javadoc-api/org/...
николай. hauschild
Я думаю, что он существовал в 3.1, но не был JavaDoced. Я не сказал, что я ненавидел, но шокирован, что @RequestParam Map<>путь не был сделан. Я немного раздражен тем, что во многих современных проектах, которые я видел в Spring MVC (весна 3.1 и выше), они добавят HttpServletRequest и HttpServletResponse в каждый метод. И кажется, потому что младшие разработчики используют StackOverflow и Google вместо того, чтобы смотреть на документ. Это затрудняет переключение проекта Spring с api сервлета на Netty API. JAX-RS имеет похожие проблемы злоупотребления, но в гораздо меньшей степени.
Адам Гент
И это JavaDoced в 3.1, просто не во всех нужных местах: « Кроме того, @RequestParam можно использовать для параметра метода Map <String, String> или MultiValueMap <String, String> для получения доступа ко всем параметрам запроса. ». На самом деле это происходит от версии 3.0 (я знал, что использовал ее до 3.1). Мое раздражение все еще заключается в том, что люди не удосужились заняться исследованием :)
Адам Гент
14

Объект HttpServletRequest уже предоставляет карту параметров. Смотрите request.getParameterMap () для более подробной информации.

Kevin
источник
1
Карта параметров Get также будет содержать данные формы из запроса POST. Если пользователь не знает ключей в строке запроса, то как он сможет отличить то, что пришло от строки запроса, а что от данных из тела POST?
nicholas.hauschild
Вы говорите мне, что собираетесь обрабатывать сообщение формы, но не знаете, каковы фактические параметры формы?
Кевин
2
В вопросе говорится, что он не знает, как называются параметры. Кроме того, я не знаю, что они тоже. ;)
nicholas.hauschild
Извините, я нахожу предпосылку немного нелепой.
Кевин
11
Это имеет смысл в приложении, управляемом данными. Тот, в котором пути запроса и строки запроса могут быть составлены клиентом, и сервер приложений затем будет искать соответствующее значение (из любого источника данных), используя эти пути и строки запроса в качестве ключей.
nicholas.hauschild
12

Вы можете просто использовать это:

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

Это должно работать нормально

Biggy_java
источник
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 с переменными name и email соответственно.

Шриранг Кадале
источник
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 Есть документы об аргументах, которые можно использовать в качестве параметров контроллера.

katoquro
источник
Спасибо, это работает. Могу я спросить, какой смысл String[]в ценности? Я должен индексировать его до 0, чтобы получить значение.
Правдаадъюстр
Может быть массив значений, таких как key=val1,val2или key=val1&key=val2(если я правильно помню, Spring поддерживает обе эти нотации), поэтому вы получите массив с 2 элементами
katoquro
6

Я могу опоздать на вечеринку, но, насколько я понимаю, вы ищете что-то вроде этого:

for(String params : Collections.list(httpServletRequest.getParameterNames())) {
    // Whatever you want to do with your map
    // Key : params
    // Value : httpServletRequest.getParameter(params)                
}
goelanshul
источник
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параметры пути.

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

www.my_site/customer/15/car/2 - ищу вторую машину 15-го покупателя.

Каким будет сценарий использования всех параметров пути на карте? Параметры пути не имеют «ключа», когда вы смотрите на сам URI, эти ключи внутри карты будут взяты из вашей аннотации @Mapping, например:

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

С точки зрения HTTP / REST параметры пути не могут быть спроецированы на карту. На мой взгляд, все дело в гибкости Spring и их желании удовлетворить любые прихоти разработчиков.

Я бы никогда не использовал карту для параметров пути, но она может быть весьма полезна для параметров запроса.

yuranos
источник