Spring MVC-如何在Spring控制器中获取地图中的所有请求参数?


183

范例网址:

../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做到这一点?

Answers:


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>
IcedD​​ante 2015年

1
谢谢你 您也可以使用标头执行相同的操作:stackoverflow.com/a/19556291/2599745
Rob Worsnop 2015年

3
这仅在请求方法为GET或POST时有效。它不适用于PUT,DELETE等请求方法。
乔治·西格古罗格

不要忘记添加import org.springframework.ui.ModelMap;
trueadjustr

@typelogic ModelMap不需要获取所有请求参数作为地图;这只是OP代码的特定细节。
xlm

34

编辑

已经指出,存在(至少从3.0开始)纯Spring MVC机制,通过它可以获取此数据。我不会在这里详述,因为这是另一个用户的答案。有关详细信息,请参见@AdamGent的答案,并且不要忘记对其进行投票。

在Spring 3.2文档中,RequestMappingJavaDoc页面和RequestParamJavaDoc页面上都提到了这种机制,但是以前,仅在RequestMapping页面上提到过。在2.5文档中,没有提及此机制。

对于大多数开发人员来说,这可能是首选的方法,因为它删除(至少是删除)HttpServletRequest与servlet-api jar定义的对象的绑定。

/编辑

您应该可以通过访问请求查询字符串request.getQueryString()

除了getQueryString,查询参数也可以作为地图从request.getParameterMap()中检索。


12
我怀疑有人不赞成这个答案,只是因为getQueryString返回的是String而不是Map。操作人员正在寻找参数图。我在您的答案中添加了getParameterMap,以帮助使其更加正确:) +1
jmort253'1

不,我不赞成这样做,因为它不是Spring MVC的方法。@RequestParam会很乐意将a Map作为参数(请参阅我的答案)。
亚当·根特

@AdamGent在Spring 3.2尚未发布时提出了这个问题。回去看看的JavaDoc 3.1,你会发现有是采用没有这样提@RequestParamMap<String,String>检索所有查询字符串参数。而且,请不要觉得这样比你在这里看到的答案憎恶,就不是那个坏:) static.springsource.org/spring/docs/3.1.x/javadoc-api/org/...
尼古拉斯。 hauschild

我认为它存在于3.1中,但不是JavaDoced。我没有说我很讨厌,但对@RequestParam Map<>未完成的方式感到震惊。在我看到过许多Spring MVC(Spring 3.1及更高版本)的现代项目中,我有些烦恼,他们会将HttpServletRequest和HttpServletResponse放在每种方法上。似乎是因为初级开发人员使用StackOverflow和google而不是查看文档。这使得Spring项目很难从servlet api转换为Netty API。JAX-RS具有类似的滥用问题,但程度要小得多。
亚当·根特

而且它在3.1中JavaDoced,而不是在所有正确的地方:“ 另外,@RequestParam可以在Map <String,String>或MultiValueMap <String,String>方法参数上使用,以访问所有请求参数。实际上,它可以一直追溯到3.0版(我知道我在3.1之前就使用过它)。我的烦恼仍然在于人们不会理会研究:)
Adam Gent 2013年

14

HttpServletRequest对象已经提供了参数映射。有关更多详细信息,请参见request.getParameterMap()


1
获取参数映射还将包含来自POST请求的表单数据。如果用户不知道查询字符串中的键,那么他们将如何区分来自查询字符串的内容和来自POST正文的数据的内容?
nicholas.hauschild

您是在告诉我要处理表单发布,但不知道实际的表单参数是什么吗?
凯文(Kevin)

2
问题指出他不知道参数名称是什么。另外,我也不知道它们是什么。;)
nicholas.hauschild

对不起,我觉得前提有点荒谬。
凯文(Kevin)

11
在数据驱动的应用程序中这很有意义。一个可以由客户端组成请求路径和查询字符串的应用程序,然后应用程序服务器将这些路径和查询字符串用作键来查找相应的值(来自任何类型的数据源)。
nicholas.hauschild

12

您可以简单地使用:

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

那应该很好


10

这是在Map获取请求参数的简单示例

 @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(),优点是,你不紧张你的应用程序和Servlet API中,WebRequest的是JavaEE模式语境对象的实例。


6

有两个接口

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

允许通用请求参数访问和request/session属性访问,而无需与本地Servlet / Portlet API绑定

例如:

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

PS 有一些关于参数的文档,可以用作Controller参数。


谢谢你的工作。请问,String[]价值的意义是什么?我必须将其索引为0只是为了获取值。
真实调节者

可能会有一个值数组,例如key=val1,val2key=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-路径参数。

我发现令人惊讶的是,在Spring MVC世界中,很多人将彼此混淆。虽然查询参数更像是搜索条件,但路径参数很可能会唯一地标识资源。话虽如此,这并不意味着您不能在URI中包含多个路径参数,因为资源结构可以嵌套。例如,假设您需要特定人员的特定汽车资源:

www.my_site/customer/15/car/2 -寻找第15位客户的第二辆车。

将所有路径参数放入地图的用例是什么?当您查看URI本身时,路径参数没有“键”,映射内的那些键将从@Mapping注释中获取,例如:

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

从HTTP / REST角度来看,路径参数实际上无法投影到地图上。我认为,这完全是关于Spring的灵活性以及他们希望适应任何开发人员的想法。

我永远不会在路径参数中使用映射,但是对于查询参数它可能非常有用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.