您的位置:首页 > 编程语言 > Java开发

Java for Web学习笔记(六十):Controller替代Servlet(2)方法中的参数

2017-06-10 17:53 549 查看

标准的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"/>


相关链接:
我的Professional Java for Web Applications相关文章
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: