标准的servlet参数
我们可以在方法的参数中获取之前熟悉的servlet参数,例如Http
@ResponseBody
@RequestMapping(value = {"/","/hello"}, params = {"name"})
public String helloName(HttpServletRequest request,@RequestParam("name")String name){
logger.info(request.getParameter("name")); //可以使用之前熟悉的servlet处理
return this.greetingService.getGreeting(name);
}
同样的我们可以获取下面的参数:
- HttpServletRequest
- HttpServletResponse
- HttpSession
- InputStream或者Reader,和Servlet中的处理一样,我们并不需要关闭它
- OutputStream或者Writer,和Servlet中的处理一样,我们并不需要关闭它
- java.util.Locale
- org.springframework.web.context.request.WebRequest,可以获取request属性和session对象,但是不能和HttpServletRequest,HttpServletResponse以及HttpSession混用
请求消息的参数:@RequestParam
参数可以自动匹配到java的原生类型,例如String, Class, File, Locale, Pattern, java.util.Properties, java.net.URL, array 或者Collection,如果我们需要自定义,也可以在java.beans.PropertyEditors or org.springframework.core.convert.converter.Converters中进行注册。
// 通过@RequestParam表示的参数缺省必须存在,否则不会匹配,会报告400错误,如:HTTP Status 400 - Required String parameter 'test' is not present。这种方式很方便,减轻了对输入信息有效性的判断的工作。
// 如果允许该参数不存在,使用required=false,不存在时值为null,或者设置defaultValue,如果不存在,设置为缺省值
// 但是在通过参数区分url匹配的时候,例如有两个方法均匹配了user,如果不将参数区分写到@RequestMapping中,是会出现匹配混淆,报告500错误,即不能依赖@RequestParam进行url匹配。书中的解析不太理解,大致是@RequestParam并未严格要求使用value作为特定参数的名称,只在本地调测起作用,或在java8的编译中加入-paramters参数。因此如果我们要通过参数来进行不同的方法适配,需要在@RequestMapping中明确指出。
@RequestMapping("user")
public String user(@RequestParam("id") long userId,
@RequestParam(value="name", required=false) String name,
@RequestParam(value="key", defaultValue="") String key){
}
如果有重复参数名字,可以使用数组等结构,例如
@RequestMapping(value = {"/test"})
public String test(@RequestParam("name")Vector<String> name)
@RequestMapping(value = {"/test"})
public String test(@RequestParam("name")String[] name)
我们还可以将所有的参数放入到Map中:
@RequestMapping(value = {"/test"})
public String test(@RequestParam Map<String, String> map)
如果有重复参数名字,可以使用 org.springframework.util.MultiValueMap:
@RequestMapping(value = {"/test"})
public String test(@RequestParam MultiValueMap<String, String> map)
请求消息头参数:@RequestHeader
Header的名字是大小写不敏感的,我们不用担心。
Map<String, String>
获取全部的的Header的值,可以采用下面方式:@ResponseBody
@RequestMapping(value = {"/test"})
public String test(@RequestHeader Map<String, String> headers){
logger.info("test : " + headers);
... ...
}
输出结果例子:
test : {accept=image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*, accept-language=zh-CN, accept-encoding=gzip, deflate, user-agent=Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko, host=localhost:8080, connection=Keep-Alive}
MultiValueMap<String, String>
获取全部的的Header的值,还可以采用下面方式:@ResponseBody
@RequestMapping(value = {"/test"})
public String test(@RequestHeader MultiValueMap<String, String> headers){
logger.info("test : " + headers);
... ...
}
输出结果例子:
test : {accept=[image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*], accept-language=[zh-CN], cache-control=[no-cache], accept-encoding=[gzip, deflate], user-agent=[Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko], host=[localhost:8080], connection=[Keep-Alive]}
HttpHeaders<String, String>
还可以采用org.springframework.http.HttpHeaders@ResponseBody
@RequestMapping(value = {"/test"})
public String test(@RequestHeader HttpHeaders<String, String> headers)
指定Header
如果获取特定的Header和获取request参数类似,例子如下:@ResponseBody
@RequestMapping("test")
public String test(@RequestHeader("Content-Type") String contentType,
@RequestHeader(value="X-Custom-Header", required=false) Date customHeader)
URL样式信息:@PathVariable
@RequestMapping(value="user/{userId}", method=RequestMethod.GET)
public String user(@PathVariable("userId") long userId)
URL样式符合正则表达式,如下:(\d :匹配一个数字字符,等价于[0-9];+代表1个或多个)
@RequestMapping(value="user/{userId:\\d+}", method=RequestMethod.GET)
public String user(@PathVariable("userId") long userId)
很显然,这种方式非常适合于RESTful消息。样式可以多个参数,如下:
@ResponseBody
@RequestMapping(value="/user/{username}/bar/{var}", method=RequestMethod.GET)
public String user(@PathVariable("username") String username,
@PathVariable("var") long var)
//或者存放到一个map中
public String user(@PathVariable Map<String, String> variables)
RFC 3986 定义了URL的参数,例如:....../hotel/43;floor=8;room=15/guest,URL匹配根据/hotel/43/guest,而floor和room属于43这部分的参数,可以通过@MatrixVariable读取
@RequestMapping("hotel/{hotelId:\\d+}/guest")
public String guestForRoom(@PathVariable("hotelId") long hotelId,
@MatrixVariable("floor") short floorNumber,
@MatrixVariable(pathVar="hotelId","room") short roomNumber) //指定在哪部分URL
//同样地,支持required,defaultValue
//同样地,我们可以用Map读出全部的信息,包括指定pathVar
【注意】我们需要在相应的配置上打开enable-matrix-variables(缺省值为false),例如在servletContext.xml上:
<mvc:annotation-driven enable-matrix-variables="true"/>