什么是数据绑定?
将HTTP请求中的参数绑定到Handler业务方法的形参
这个参数非常重要。web项目其实就是客户端跟服务器之间的交互,客户端发送请求,服务器对请求做出响应。
客户端发送请求的时候,是需要携带参数过来的。比如查询课程的详细信息,前台就会将课程的id传给后台,后台通过id在数据库里面检索出该门课程的所有的详细信息,然后把这个结果集封装成一个模型数据,再把这个模型数据返回给前台做一个响应,这就是完整的流程。
springmvc之前获取参数的操作:serlvet当中的doget和dopost方法就是用来处理这种请求的。
这两个方法中形参列表有默认的参数,是httpservletrequest类型的request对象,通过这个request对象获取参数
但是通过这个request对象会有一个问题,拿出来的都是string类型的,比如说前台传过来一个int类型的id,那我们在后台从request对象拿出来之后,它是一个string类型的,因此就需要做一个数据类型的转换,将string类型转换为int类型。如果说要添加一个课程,就需要在前端页面输入相关属性,比如输入它的id,名称以及价格等。form表单提交之后,会作为参数传给后台。在后台的业务方法中,通过request对象把这些参数拿出来之后,还是需要将它封装成一个课程对象。
也就是说通过原生的方式需要进行一系列重复的操作,包括数据类型的转换以及封装等繁琐的步骤。
如果使用springmvc框架,springmvc框架就会帮助我们完成这些一系列步骤,不需要自己去写了。
springmvc框架业务层当中,需要什么就在形参列表定义什么,假如说要获取int类型的id,那就在形参列表定义一个int类型的形参,springmvc框架会自动的将http请求的参数拿出来绑定到形参当中
如果说要做一个添加课程的操作,那就在形参列表当中,定义一个课程类型的对象,springmvc框架会自动从请求当中的参数拿出来,封装到这个对象当中。springmvc框架会帮我们完成这样的操作。我们在业务方法中直接拿到现成的、需要的结果去完成后续的业务逻辑操作即可。
那么springmvc框架底层如何实现这样的过程的呢?
通过HandlerAdapter去调用HttpMessageConverter组件去完成数据绑定的,把这个数据绑定到Handler的业务方法的形参列表当中。
完成流程:前端发送请求过来,被DispatcherServlet所捕获,DispatcherServlet会将这个请求映射到Handler,然后去调用HandlerAdapter,HandlerAdapter在执行业务方法之前,会调用HttpMessageConverter组件,将http请求的参数拿出来进行数据类型转换以及封装等一系列步骤操作,把最终绑定的结果直接赋值给Handler的业务方法的形参列表当中
这样我们在业务方法当中就可以直接拿这个封装好的、现成的形参去完成后续的业务逻辑操作。也就是说在springmvc框架中,不需要完成对参数的一些额外的处理,springmvc框架会自动的帮我们完成。
常用的数据类型:基本数据类型、包装类、数组、对象、集合(List,Set,Map)、JSON
下面是实例的一些主要代码:
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<context:component-scan base-package="com.lzy"></context:component-scan>
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!--配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--配置前缀-->
<property name="prefix" value="/"></property>
<!--配置后缀-->
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
控制层:
package com.lzy.controller;
import com.lzy.dao.CourseDAO;
import com.lzy.entity.Course;
import com.lzy.entity.CourseList;
import com.lzy.entity.CourseMap;
import com.lzy.entity.CourseSet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class DataBindController {
//测试基本数据类型的绑定
@RequestMapping(value = "/baseType")
@ResponseBody
//@ResponseBody注解:直接返回结果给客户端,不跳转jsp页面
//@RequestParam注解:将http请求的id绑定到形参当中
public String baseType(@RequestParam(value = "id") int id) {
//直接返回拼接的字符串给客户端
return "id:" + id;
}
//测试包装类的绑定
@RequestMapping(value = "/packageType")
@ResponseBody
public String packageType(@RequestParam(value = "id") Integer id) {
return "id:" + id;
}
//测试数组
//第一步 拼接字符串
//第二步 遍历数组
@RequestMapping(value = "/arrayType")
@ResponseBody
public String arrayType(String[] name) {
//拼接字符串使用StringBuffer
StringBuffer sbf = new StringBuffer();
//遍历数组
for (String item : name) {
sbf.append(item).append(" ");
}
//将string类型的值返回给前端
return sbf.toString();
}
@Autowired
private CourseDAO courseDAO;
//测试对象
@RequestMapping(value = "/pojoType")
//由于返回的是ModelAndView,ModelAndView里带有视图信息,直接返回视图即可,这时候就不需要添加@ResponseBody了
public ModelAndView pojoType(Course course) {
//保存对象
courseDAO.add(course);
//响应
ModelAndView modelAndView = new ModelAndView();
//添加视图信息
modelAndView.setViewName("index");
//添加模型数据
modelAndView.addObject("courses", courseDAO.getAll());
return modelAndView;
}
//测试list集合
@RequestMapping(value = "/listType")
public ModelAndView listType(CourseList courseList) {
for (Course course : courseList.getCourses()) {
courseDAO.add(course);
}
//响应
ModelAndView modelAndView = new ModelAndView();
//添加视图信息
modelAndView.setViewName("index");
//添加模型数据
modelAndView.addObject("courses", courseDAO.getAll());
return modelAndView;
}
//测试Map集合
@RequestMapping(value = "/mapType")
public ModelAndView mapList(CourseMap courseMap){
for(String key:courseMap.getCourses().keySet()){
Course course = courseMap.getCourses().get(key);
courseDAO.add(course);
}
//响应
ModelAndView modelAndView = new ModelAndView();
//添加视图信息
modelAndView.setViewName("index");
//添加模型数据
modelAndView.addObject("courses", courseDAO.getAll());
return modelAndView;
}
//测试Set集合
@RequestMapping(value = "/setType")
public ModelAndView setType(CourseSet courseSet){
for(Course course:courseSet.getCourses()){
courseDAO.add(course);
}
//响应
ModelAndView modelAndView = new ModelAndView();
//添加视图信息
modelAndView.setViewName("index");
//添加模型数据
modelAndView.addObject("courses", courseDAO.getAll());
return modelAndView;
}
//测试json
@RequestMapping(value = "/jsonType")
public Course jsonType(@RequestBody Course course){
course.setPrice(course.getPrice()+100);
return course;
}
}