SpringMVC核心——参数获取与Servlet资源获取问题
一、SpringMVC 使用 @PathVariable、@RequestParam、@RequestHeader、@CookieValue 等来解决参数获取问题。
1. @PathVariable:映射 URL 绑定的占位符,可以借助于传入到方法参数列表中的 @PathVariable 注解获取到 URL 映射中的参数值。如:
<a href="handler01/1">test pathvariable</a>
@RequestMapping("/handler01/{id}")
public String testPathVariable(@PathVariable("id") String id) {
System.out.println("id:" + id);
return "success";
}
说明:URL 绑定占位符使 SpringMVC 对 REST 提供了支持。对于具体的 SpringMVC 的 REST 风格的例子会在以后的文章里介绍。
2.@RequestParam
官方文档是这样描述的:
* Annotation which indicates that a method parameter should be bound to a web |
说明一下:
(1)该注解表明 web 请求参数绑定到目标 handler 方法的入参。
(2)如果方法的入参类型是一个 Map,不包含泛型类型,并且请求参数名称是被指定的
(如:public String testRequestParam5(@RequestParam("userName") Map map)),请求参数会被转换为一个 Map,前提是存在转换策略。
这里所说的转换策略,通常是指 请求参数 到 Map 的类型转换,如请求参数为 userName=a|12,b|34 这样的数据,需要通过一个转换策略(类型转换器)
来完成 a|12,b|34 到 map 的转换。在我们一般开发的过程中,不包含这种情况。是一种扩展。关于类型转换会在后面的文章中介绍。
(3)如果方法的入参是一个 Map 且指定了泛型类型 Map<String,String> 或者是 org.springframework.util.MultiValueMap 类型的 MultiValueMap<String, String>
并且没有指定请求参数,那么这个 Map 类型的参数会将所有的请求参数名称和值填充(populate)到其中。
如:
请求:<a href="testRequestParam4?userName=jack&age=23">test request param4</a>
handler 方法:
@RequestMapping("/testRequestParam4")
public String testRequestParam4(@RequestParam Map<String, String> map) {
System.out.println("map:" + map);
return "success";
}
控制台输出:
map:{userName=jack, age=23}
上面整体介绍了 @RequestParam,下面详细看看它的API:
包含三个属性:
(1)value 属性,默认为 ""
官方文档说明:
The name of the request parameter to bind to.
解释的已经很明白了,不再赘述。
(2)required 属性,默认为 true
官方文档说明:Whether the parameter is required.
见名知意,该请求参数是否是必须的。为 true 的请求下,若请求参数中没有,则会抛出一个异常。为 false 的情况下,如果请求参数中没有,则方法入参对应值为 null。
另外,提供一个 defaultValue 属性,则会是此属性设置为 false。
(3)defaultValue 属性
当没有提供对应的请求参数,或者请求参数为空时,会使用此属性对应的值。当设置此属性的时候,会将 required 属性设置为 false。
下面提供几个常见请求情况的例子:
(1)请求为:<a href="testRequestParam?userName=abc">test request param</a>
handler 方法:
@RequestMapping("/testRequestParam")
public String testRequstParam01(@RequestParam("userName") String userName) {
System.out.println("userName: " + userName); return "success";
}
(2)请求为:<a href="testRequestParam2?userName=jack&userName=lucy">test request param2</a>
handler 方法:
@RequestMapping("/testRequestParam2")
public String testRequestParam02(@RequestParam("userName") List<String> userNames) {
System.out.println("userNames:" + userNames);
return "success";
}
控制台输出:
userNames:[jack, lucy]
(3)请求为:<a href="testRequestParam4?userName=jack&age=23">test request param4</a>
handler 方法:
@RequestMapping("/testRequestParam4")
public String testRequestParam4(@RequestParam Map<String, String> map) {
System.out.println("map:" + map);
return "success";
}
控制台输出:
map:{userName=jack, age=23}
主要就分为这三种情况,其中第一种最为常用,第二种和第三种很少能想到,若能想到的话,能为我们开发节省不少时间。
3.@RequestHeader
官方文档中是这样描述的:
Annotation which indicates that a method parameter should be bound to a web request header. |
和 @RequestParam 描述类似,只不过绑定的是 web 请求头信息到方法入参。
定义的三个属性和 @RequestParam 一样,默认值和使用的方法也一样。由于用的比较少,这里只做一个例子说明:
请求:<a href="testRequestHeader">test request header</a>
handler 方法:
@RequestMapping("/testRequestHeader")
public String testRequestHeader(@RequestHeader(value = "Accept", required = false) String accept) {
System.out.println("accept:" + accept);
return "success";
}
控制台输出:
accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
4.@CookieValue
官方文档描述:
Annotation which indicates that a method parameter should be bound to an HTTP cookie. |
绑定一个 http cookie 到方法的入参,其中 value 属性表明要入参的 cookie 的 key。
默认值和使用方式和 @RequestParam 类似。
例子:
请求:<a href="testCookieValue">test cookie value</a>
handler 方法:
@RequestMapping("/testCookieValue")
public String testCookieValue(@CookieValue(value = "JSESSIONID", required = false) String sessionId) {
System.out.println("sessionId:"+sessionId);
return "success";
}
控制台输出:
sessionId:9D16BDF7063E1BFD9A0C052F1B109A0D
5.绑定请求参数到方法入参处的 bean 对象。
先看两个例子:
(1)绑定请求参数到 bean
请求:包括 get 和 post 请求方式提交的情况。
<a href="testBean?personName=jack&age=23">test bean</a>
<form action="testBean" method="post">
<label>
personName:<input type="text" name="personName"/>
</label>
<label>
age:<input type="text" name="age"/>
</label>
<input type="submit" value="submit"/>
</form>
handler 方法:
@RequestMapping("/testBean")
public String testBean(Person person) {
System.out.println(person);//Person{personName='jack', age='23'}
return "success";
}
发现不论是通过 get 方式,还是post 方式,都可以将对应的请求参数注入到对应的 bean 中。
(2)绑定请求参数到级联的 bean
bean 的结构:
/**
* @author solverpeng
* @create 2016-08-04-9:43
*/
public class Employee {
private String empName;
private Address address; public String getEmpName() {
return empName;
} public void setEmpName(String empName) {
this.empName = empName;
} public Address getAddress() {
return address;
} public void setAddress(Address address) {
this.address = address;
} @Override
public String toString() {
return "Employee{" +
"empName='" + empName + '\'' +
", address=" + address +
'}';
}
}
Employee
/**
* @author solverpeng
* @create 2016-08-04-9:43
*/
public class Address {
private String addressName; public String getAddressName() {
return addressName;
} public void setAddressName(String addressName) {
this.addressName = addressName;
} @Override
public String toString() {
return "Address{" +
"addressName='" + addressName + '\'' +
'}';
}
}
Address
请求:同样包含 get 请求 和 post 请求
<a href="testBeanCascade?empName=jack&address.addressName=beijing">test bean cascade</a> <form action="testBeanCascade" method="post">
<label>
empName:<input type="text" name="empName"/>
</label>
<label>
Address:<input type="text" name="address.addressName"/>
</label>
<input type="submit" value="submit"/>
</form>
handler 方法:
@RequestMapping("/testBeanCascade")
public String testBeanCascade(Employee employee) {
System.out.println(employee);//Employee{empName='jack', address=Address{addressName='beijing'}}
return "success";
}
是如何绑定的呢?翻源码过程如下:
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter#invokeHandlerMethod
ExtendedModelMap implicitModel = new BindingAwareModelMap();
Object result = methodInvoker.invokeHandlerMethod(handlerMethod, handler, webRequest, implicitModel);
第一步:发现在 result 中已经包含了注入的 bean。所以注入是在methodInvoker.invokeHandlerMethod() 方法中做的。
第二步:org.springframework.web.bind.annotation.support.HandlerMethodInvoker#invokeHandlerMethod
Object[] args = resolveHandlerArguments(handlerMethodToInvoke, handler, webRequest, implicitModel);
第三步:org.springframework.web.bind.annotation.support.HandlerMethodInvoker#resolveHandlerArguments
doBind(binder, webRequest, validate, validationHints, !assignBindingResult);// 这里进行的绑定
第四步:org.springframework.web.bind.ServletRequestDataBinder#bind
doBind(mpvs);
第五步:org.springframework.validation.DataBinder#doBind
this.applyPropertyValues(mpvs);
最终发现,是在 DataBinder 这个类的 doBind() 方法中进行的绑定。在翻源码的过程中,发现 resolveHandlerArguments() 方法值得大家看一看,不论水平高低,
其实真正解决 SpringMVC 参数问题就是在这个方法中解决的。
总结一下:Spring MVC 会按请求参数名和 POJO 属性名进行自动匹配,自动为该对象填充属性值。支持级联属性。
二、SpringMVC 解决 Servlet 资源获取问题
1. SpringMVC 使用 Servlet 资源作为方法的入参来解决 Servlet 资源获取问题。
2.可以作为入参的 Servlet 资源有:HttpServletRequest、HttpServletResponse、HttpSession、Locale、InputStream、OutputStream、Reader、Writer
3.例子:
使用 HttpServletRequest 作为入参
请求:<a href="testServletAPI">test servlet api</a>
handler 方法:
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request) {
String id = request.getSession().getId();
System.out.println("sessionId:" + id);
return "success";
}
控制台输出:
sessionId:E369037AF3DC276BA78539F0AF5C044B
其他的 Servlet 资源这里就不在赘述。
三、总结
SpringMVC 使用 @PathVariable 来获取 @RequestMapping 中占位符的值,为 REST 风格的程序的编写提供了支持。使用 @RequestParam 能接收绝大部分请求参数,同时提供了类型
转换这种扩展。使用 @RequestHeader 来映射请求头信息。使用 @CookieValue 来映射 http cookie 信息。同时还支持模型的注入。也可以获取到原生的 servlet 资源。即在目标的方法处,
我们可以获取到任何我们想要的资源,SpringMVC 对这个过程进行了简化,使开发更加便捷,灵活。
SpringMVC核心——参数获取与Servlet资源获取问题的更多相关文章
- 传值:web.xml传递参数 即在Servlet中获取web.xml里的值
传值:web.xml传递参数 在web.xml中的Servlet里配置多个init-param <servlet> ... <init-param> <param-nam ...
- Javaweb学习笔记——(九)——————Servlet的进入,及ServletConfig、GenericServlet、HttpServlet、ServletContext、获取类路径资源
Servlet1.什么是Servlet? *Servlet是Javaweb三大组件之一(Servlet,Filter,Listener) *Servlet是用来处理客户端请求的动态资源 *Servle ...
- springMVC(spring)+WebSocket案例(获取请求参数)
开发环境(最低版本):spring 4.0+java7+tomcat7.0.47+sockjs 前端页面要引入: <script src="http://cdn.jsdelivr.ne ...
- servlet中获取配置文件中的参数.
web.xml (添加init-param) <?xml version="1.0" encoding="UTF-8"?> <web-app ...
- SpringMVC请求参数的获取方式
一.GET请求参数获取 1. 通过HttpServletRequest获取参数 2. 直接方法参数获取 3. RequestParam注解方式获取请求参数 4. Bean方式获取参数 5. Model ...
- springmvc请求参数获取的几种方法
1.直接把表单的参数写在Controller相应的方法的形参中,适用于get方式提交,不适用于post方式提交. /** * 1.直接把表单的参数写在Controller相应的方法的形参中 * @pa ...
- springmvc请求参数获取(自动绑定)的几种方法
1.直接把表单的参数写在Controller相应的方法的形参中,适用于get方式提交,不适用于post方式提交. /** * 1.直接把表单的参数写在Controller相应的方法的形参中 * @pa ...
- web.xml中在Servlet中获取context-param和init-param内的参数
引自:http://blog.csdn.net/yakson/article/details/9203231 web.xml里面可以定义两种参数:1.application范围内的参数,存放在serv ...
- servlet自动获取前端页面提交数据
servlet自动获取前端页面jsp提交数据 以下是本人在学习过程中,因前端页面提交参数过多,后台servlet封装实体类过于麻烦而写的一个工具类,应用于jsp/servlet数据提交后,基于MVC+ ...
随机推荐
- 如何在maven项目的pom.xml文件中添加jar包
在使用maven进行项目开发时,我们需要在pom.xml文件中添加自己所需要的jar包.这就要求我们获取jar包的groupId和artifactId. 我们可以在一些maven仓库上搜索我们所需要的 ...
- WPF与winform与silverlight的区别
收到了一封学生的邮件: =========================== 金老师您好: 最近在学C#.NET,基本语法学习的差不多了,接下来准备学习图形界面设计部分.但是我目前对于.NET的Wi ...
- Linux下tomcat部署
进入Tomcat下的bin目录 cd /usr/local/tomcat/bin 如果你想直接干掉Tomcat,你可以使用kill命令,直接杀死Tomcat进程 kill -9 7010 然后继续查看 ...
- javaweb 学习总结
http://www.cnblogs.com/xdp-gacl/category/574705.html 这个总结很好,以前看书没搞懂的,这里基本上都清楚了,赞一个,推荐. Servlet与普通Jav ...
- 一篇不错的讲解Java异常的文章(转载)原作者已没法考证
六种异常处理的陋习 你觉得自己是一个Java专家吗?是否肯定自己已经全面掌握了Java的异常处理机制?在下面这段代码中,你能够迅速找出异常处理的六个问题吗? 1 OutputStreamWriter ...
- Linux文件和windows文件在 换行符的区别
Linux或Unix文件,和windows文件,在来回处理时,如果不注意 换行符的区别,可能导致程序错误!!!深刻的教训.... 在早期的打印机时代,开始新的一行要占用两个字符的时间.如果到了一行的结 ...
- [转]Android 超高仿微信图片选择器 图片该这么加载
快速加载本地图片缩略图的方法: 原文地址:Android 超高仿微信图片选择器 图片该这么加载 其示例代码下载: 仿微信图片选择器 ImageLoader
- 写给已有编程经验的 Python 初学者的总结【转】
当我开始学习Python的时候,有些事我希望我一早就知道.我花费了很多时间才学会这些东西.我想要把这些重点都编纂到一篇文章当中.这篇文章的目标读者,是刚刚开始学习Python语言的有经验的程序员,想要 ...
- Solve: Your project references the latest version of Entity Framework (for MySQL) in Visual Studio 2013
The error message while trying to create a ADO.net Entity Data Model ( Entity Framework 6 ) for MySq ...
- Jenkins 安装或更新插件失败
试试这个插件网址是否可以在网页中打开 http://mirror.xmission.com/jenkins/updates/current/update-center.json 如可以,把这个网址 ...