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

SpringMVC数据绑定使用篇(1)

2017-06-15 00:00 183 查看
#1.概述
使用SpringMVC进行开发,controller 内的方法最终都不是我们自己去调用的,

而是由SpringMVC根据请求映射,处理...一系列步骤后去调用了我们编写的

controller中的方法。那么SpringMVC是如何按照我们定义的参数列表将参数

传递的呢?本篇中先对SpringMVC的参数绑定的使用进行讲解说明,不会过

多的设计到源码和原理。后续的章节将会详细剖析源码和原理,让SpringMVC

的爱好者或者热爱学习的同学们对SpringMVC框架有更加深刻透彻的认识。

(不加班,将实践总结为理论的过程也是很有乐趣的:)

1.1 基本原理

使用Java的同学都知道反射机制,SpringMVC之所以能够调用我们在controller

内的方法就是使用了反射机制实现的,如果还记得反射调用方法的代码那么它

大概应该是这个样子的:

public Object invoke(Object obj, Object... args)

SpringMVC 的源代码也是如此实现的:

// org.springframework.web.method.support.InvocableHandlerMethod 中
protected Object doInvoke(Object... args) throws Exception {
ReflectionUtils.makeAccessible(getBridgedMethod());
try {
return getBridgedMethod().invoke(getBean(), args);
}
// ......
}

大多数同学现在应该也猜到了,参数绑定的秘密就在于 args 这个参数的产生过程。

#1.web元素绑定
在进行WEB开发的时候我们经常需要使用到HttpServletRequest 、

HttpServletResponse 、HttpSession 这些对象进行操作。只要我们
代码工作在Servlet容器中那么我们总是能够获取到这些对象的。使用
过或者熟悉 struts2 的同学应该还记得,如果我们希望获取到这些对象
那么我们的Action就需要去继承一些XXXAware类,这样做的缺点就是
框架对我们的代码有较大的侵入性。而且就从使用角度来讲这样也不是

很受广大程序员的喜爱。
同样的功能SpringMVC提供了更加简洁的方式,让你的代码变得 clean

// 绑定 HttpServletRequest 对象
public ModelAndView requestBindHandler(HttpServletRequest request){ // ... }
// 绑定 HttpServletResponse 对象
public ModelAndView responseBindHandler(HttpServletResponse response) { // ... }
// 绑定 HttpSession 对象
public ModelAndView sessionBindHandler(HttpSession session) {// ... }
// 绑定 Cookie
public ModelAndView cookieBindHandler(@CookieValue("JSESSIONID") String cookie)
// 绑定 RequestHeader
public ModelAndView headerBindHandler(@RequestHeader("Accept-Language") String acceptLanguage)


2.简单数据类型绑定

int & Integer

public ModelAndView intBindHandler(int integer) { // ... }
public ModelAndView integerBindHandler(Integer integer) { // ...  }

这两种方式都可以完成参数的绑定,前端只需要按照这里的参数名称(如:integer)

为参数名进行参数的传递即可,如图:



**以上两种方式最大的区别就在于,参数为 int 的时候如果前端没有传递这个参数过来那么SpringMVC会抛出 IllegalStateException , 而 Integer 则不会,只会接收到一个 null **。

byte & Byte , short & Short , long & Long , float & Float ,

double & Double 行为和 int & Integer 一致 。

String 类型也和上述行为差不多,只不过 String 是引用类型不会出现

如果没有传递该参数就抛出异常的问题
7fe0


boolean & Boolean 的行为比较特殊 , 如果前端没有传递请求参数

SpringMVC会默认将参数设置为 false :

private Object handleNullValue(String name, Object value, Class<?> paramType) {
if (value == null) {
if (Boolean.TYPE.equals(paramType)) {
return Boolean.FALSE;
}
else if (paramType.isPrimitive()) {
throw new IllegalStateException("Optional " + paramType.getSimpleName() + " parameter '" + name +
"' is present but cannot be translated into a null value due to being declared as a " +
"primitive type. Consider declaring it as object wrapper for the corresponding primitive type.");
}
}
return value;
}


3.简单数据类型数组、集合类型绑定

数组绑定

public ModelAndView arrayBindHandler(String[] arr)




List 绑定

public ModelAndView listBindHandler(@RequestParam List<String> list)




Set 绑定

public ModelAndView setBindHandler(@RequestParam Set<String> set)




Map 绑定

public ModelAndView mapBindHandler(@RequestParam Map<Object,Object> map)




简单 POJO 绑定

public ModelAndView pojoBindHandler(User user)




JSON 格式的参数绑定

// 利用 @RequestBody 完成 json 反序列化成 POJO
public ModelAndView jsonBindHandler(@RequestBody User user)




** 需要注意的一点是:如果按照上述例子无法正常实现,抛出 HttpMediaTypeNotSupportedException

,原因是 SpringMVC 的 HandlerMethodArgumentResolver 中没有

MappingJackson2HttpMessageConverter 类型的实例 , 引发这个问题的原应是 classpath 路径下没有jackson 的 jar 包。
**

相同参数名称,对应多的变量

public ModelAndView sameNameArgBindHand(User user,String name)
当有一个名称为 "name" 的参数被传递时 , 对象 user 中的 name 属性 , 和另一个参数 name 都会被赋值


POJO 类型的集合绑定

public ModelAndView listPojoBindHadnler(MultipleUserWrap userWrap)

public class MultipleUserWrap {
List<User> users;
public List<User> getUsers() {
return users;
}
public MultipleUserWrap setUsers(List<User> users) {
this.users = users;
return this;
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  SpringMVC 数据绑定