SpringMVC强大的数据绑定

到目前为止,请求已经能交给我们的处理器进行处理了,接下来的事情是要进行收集数据啦,接下来我们看看我们能从请求中收集到哪些数据,如图6-11:

图6-11

1、@RequestParam绑定单个请求参数值;

2、@PathVariable绑定URI模板变量值;

3、@CookieValue绑定Cookie数据值

4、@RequestHeader绑定请求头数据;

5、@ModelValue绑定参数到命令对象;

6、@SessionAttributes绑定命令对象到session;

7、@RequestBody绑定请求的内容区数据并能进行自动类型转换等。

8、@RequestPart绑定“multipart/data”数据,除了能绑定@RequestParam能做到的请求参数外,还能绑定上传的文件等。

除了上边提到的注解,我们还可以通过如HttpServletRequest等API得到请求数据,但推荐使用注解方式,因为使用起来更简单。

接下来先看一下功能处理方法支持的参数类型吧。

6.6.1、功能处理方法支持的参数类型

在继续学习之前,我们需要首先看看功能处理方法支持哪些类型的形式参数,以及他们的具体含义。

一、ServletRequest/HttpServletRequest 和 ServletResponse/HttpServletResponse

Java代码

  1. public String requestOrResponse (
  2. ServletRequest servletRequest, HttpServletRequest httpServletRequest,
  3. ServletResponse servletResponse, HttpServletResponse httpServletResponse
  4. )

Spring Web MVC框架会自动帮助我们把相应的Servlet请求/响应(Servlet API)作为参数传递过来。

二、InputStream/OutputStream 和 Reader/Writer

Java代码

  1. public void inputOrOutBody(InputStream requestBodyIn, OutputStream responseBodyOut)
  2. throws IOException {
  3. responseBodyOut.write("success".getBytes());
  4. }

requestBodyIn:获取请求的内容区字节流,等价于request.getInputStream();

responseBodyOut:获取相应的内容区字节流,等价于response.getOutputStream()。

Java代码

  1. public void readerOrWriteBody(Reader reader, Writer writer)
  2. throws IOException {
  3. writer.write("hello");
  4. }

reader:获取请求的内容区字符流,等价于request.getReader();

writer:获取相应的内容区字符流,等价于response.getWriter()。

InputStream/OutputStream 和 Reader/Writer两组不能同时使用,只能使用其中的一组。

三、WebRequest/NativeWebRequest

WebRequest是Spring Web MVC提供的统一请求访问接口,不仅仅可以访问请求相关数据(如参数区数据、请求头数据,但访问不到Cookie区数据),还可以访问会话和上下文中的数据;NativeWebRequest继承了WebRequest,并提供访问本地Servlet API的方法。

Java代码

  1. public String webRequest(WebRequest webRequest, NativeWebRequest nativeWebRequest) {
  2. System.out.println(webRequest.getParameter("test"));//①得到请求参数test的值
  3. webRequest.setAttribute("name", "value", WebRequest.SCOPE_REQUEST);//②
  4. System.out.println(webRequest.getAttribute("name", WebRequest.SCOPE_REQUEST));
  5. HttpServletRequest request =
  6. nativeWebRequest.getNativeRequest(HttpServletRequest.class);//③
  7. HttpServletResponse response =
  8. nativeWebRequest.getNativeResponse(HttpServletResponse.class);
  9. return "success";
  10. }

① webRequest.getParameter:访问请求参数区的数据,可以通过getHeader()访问请求头数据;

② webRequest.setAttribute/getAttribute:到指定的作用范围内取/放属性数据,Servlet定义的三个作用范围分别使用如下常量代表:

SCOPE_REQUEST :代表请求作用范围;

SCOPE_SESSION :代表会话作用范围;

SCOPE_GLOBAL_SESSION :代表全局会话作用范围,即ServletContext上下文作用范围。

③ nativeWebRequest.getNativeRequest/nativeWebRequest.getNativeResponse:得到本地的Servlet API。

四、HttpSession

Java代码

  1. public String session(HttpSession session) {
  2. System.out.println(session);
  3. return "success";
  4. }

此处的session永远不为null。

注意:session访问不是线程安全的,如果需要线程安全,需要设置AnnotationMethodHandlerAdapter或RequestMappingHandlerAdapter的synchronizeOnSession属性为true,即可线程安全的访问session。

五、命令/表单对象

Spring Web MVC能够自动将请求参数绑定到功能处理方法的命令/表单对象上。

Java代码

  1. @RequestMapping(value = "/commandObject", method = RequestMethod.GET)
  2. public String toCreateUser(HttpServletRequest request, UserModel user) {
  3. return "customer/create";
  4. }
  5. @RequestMapping(value = "/commandObject", method = RequestMethod.POST)
  6. public String createUser(HttpServletRequest request, UserModel user) {
  7. System.out.println(user);
  8. return "success";
  9. }

如果提交的表单(包含username和password文本域),将自动将请求参数绑定到命令对象user中去。

六、Model、Map、ModelMap

Spring Web MVC 提供Model、Map或ModelMap让我们能去暴露渲染视图需要的模型数据。

Java代码

  1. @RequestMapping(value = "/model")
  2. public String createUser(Model model, Map model2, ModelMap model3) {
  3. model.addAttribute("a", "a");
  4. model2.put("b", "b");
  5. model3.put("c", "c");
  6. System.out.println(model == model2);
  7. System.out.println(model2 == model3);
  8. return "success";}

虽然此处注入的是三个不同的类型(Model model, Map model2, ModelMap model3),但三者是同一个对象,如图6-12所示:

图6-11

AnnotationMethodHandlerAdapter和RequestMappingHandlerAdapter将使用BindingAwareModelMap作为模型对象的实现,即此处我们的形参(Model model, Map model2, ModelMap model3)都是同一个BindingAwareModelMap实例。

此处还有一点需要我们注意:

Java代码

  1. @RequestMapping(value = "/mergeModel")
  2. public ModelAndView mergeModel(Model model) {
  3. model.addAttribute("a", "a");//①添加模型数据
  4. ModelAndView mv = new ModelAndView("success");
  5. mv.addObject("a", "update");//②在视图渲染之前更新③处同名模型数据
  6. model.addAttribute("a", "new");//③修改①处同名模型数据
  7. //视图页面的a将显示为"update" 而不是"new"
  8. return mv;
  9. }

从代码中我们可以总结出功能处理方法的返回值中的模型数据(如ModelAndView)会 合并 功能处理方法形式参数中的模型数据(如Model),但如果两者之间有同名的,返回值中的模型数据会覆盖形式参数中的模型数据。

七、Errors/BindingResult

Java代码

  1. @RequestMapping(value = "/error1")
  2. public String error1(UserModel user, BindingResult result)

Java代码

  1. @RequestMapping(value = "/error2")
  2. public String error2(UserModel user, BindingResult result, Model model) {

Java代码

  1. @RequestMapping(value = "/error3")
  2. public String error3(UserModel user, Errors errors)

以上代码都能获取错误对象。

Spring3.1之前(使用AnnotationMethodHandlerAdapter)错误对象必须紧跟在命令对象/表单对象之后,如下定义是错误的:

Java代码

  1. @RequestMapping(value = "/error4")
  2. public String error4(UserModel user, Model model, Errors errors)
  3. }

如上代码从Spring3.1开始(使用RequestMappingHandlerAdapter)将能正常工作,但还是推荐“错误对象紧跟在命令对象/表单对象之后”,这样是万无一失的。

Errors及BindingResult的详细使用请参考4.16.2数据验证。

八、其他杂项

Java代码

  1. public String other(Locale locale, Principal principal)

java.util.Locale:得到当前请求的本地化信息,默认等价于ServletRequest.getLocale(),如果配置LocaleResolver解析器则由它决定Locale,后续介绍;

java.security.Principal:该主体对象包含了验证通过的用户信息,等价于HttpServletRequest.getUserPrincipal()。

以上测试在cn.javass.chapter6.web.controller.paramtype.MethodParamTypeController中。

其他功能处理方法的形式参数类型(如HttpEntity、UriComponentsBuilder、SessionStatus、RedirectAttributes)将在后续章节详细讲解。

第二部分会介绍注解方式的数据绑定。

时间: 2024-08-24 12:00:17

SpringMVC强大的数据绑定的相关文章

SpringMVC类型转换、数据绑定详解[附带源码分析]

目录 前言 属性编辑器介绍 重要接口和类介绍 部分类和接口测试 源码分析 编写自定义的属性编辑器 总结 参考资料 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:http://www.cnblogs.com/fangjian0423/p/springMVC-introduction.html public String method(Integer num, Date birth) { ... } Http请求传递的数据都是字符串S

SpringMVC类型转换、数据绑定详解

public String method(Integer num, Date birth) { ... } Http请求传递的数据都是字符串String类型的,上面这个方法在Controller中定义,如果该方法对应的地址接收到到浏览器的请求的话,并且请求中含有num和birth参数,那么num会被自动转换成Integer对象:birth会被自动转为Date对象(Date转换需要配置属性编辑器). 本文将分析这一原理,解释SpringMVC是如何实现数据类型的转换. 属性编辑器介绍 在讲解核心内

SpringMVC 强大的注解方式,走一个流程,看看,这些注解用过么

实现方式一: Controller层: 1 import java.util.List; 2 import java.util.Map; 3 import java.util.NoSuchElementException; 4 import java.util.Optional; 5 6 import org.apache.commons.lang3.StringUtils; 7 import org.bson.types.ObjectId; 8 import org.slf4j.helpers

跟我学SpringMVC目录汇总贴、PDF下载、源码下载

跟我学SpringMVC目录汇总贴.PDF下载.源码下载 http://jinnianshilongnian.iteye.com/blog/1752171 跟开涛学SpringMVC 在线版目录 第一章 Web MVC简介 第二章 Spring MVC入门 第三章 DispatcherServlet详解 第四章 Controller接口控制器详解(1) 第四章 Controller接口控制器详解(2) 第四章 Controller接口控制器详解(3) 第四章 Controller接口控制器详解(

《转载》跟我学SpringMVC

在线版目录 第一章 Web MVC简介 第二章 Spring MVC入门 第三章 DispatcherServlet详解 第四章 Controller接口控制器详解(1) 第四章 Controller接口控制器详解(2) 第四章 Controller接口控制器详解(3) 第四章 Controller接口控制器详解(4) 第四章 Controller接口控制器详解(5) 第四章 Controller接口控制器详解(6) 第五章 处理器拦截器详解 第六章 注解式控制器详解 注解式控制器运行流程及处理

springMVC能做什么,做j2ee时候要考虑什么

转载: http://jinnianshilongnian.iteye.com/category/231099 [置顶] 跟我学SpringMVC目录汇总贴.PDF下载.源码下载 博客分类: 跟开涛学SpringMVC 电子书下载链接 请登录后下载   在线版目录 第一章 Web MVC简介 第二章 Spring MVC入门 第三章 DispatcherServlet详解 2012-12-22 08:05 浏览 188903 评论(91) 收藏 分类:企业架构 源代码下载——第七章 注解式控制器

Spring MVC(总结)

为了学习Spring MVC特意去网上找了一些博乐来学习,意外中发现了跟开涛学SpringMVC这个专栏,为了更好地学习掌握,和分享给大家,所以自己将他的博文全部转载过来,方便后期的学习,在这里感谢这位博主辛苦整理的博文,其内容讲解详细透彻,值得学习! 下面是博主分享的资源:(分享给大家,也是尊重原创,强烈推荐此为博主,也希望大家能够支持我!) 电子书下载链接  在线版目录 第一章 Web MVC简介 第二章 Spring MVC入门 第三章 DispatcherServlet详解 第四章 Co

Spring3.2新注解@ControllerAdvice

Spring3.2新注解@ControllerAdvice @ControllerAdvice,是spring3.2提供的新注解,从名字上可以看出大体意思是控制器增强.让我们先看看@ControllerAdvice的实现: Java代码   @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface ControllerAdvice { } 没什么特别

SpringMVC Checkbox 对List<object> 数据绑定

在SpringMVC中不得不用到强大的数据绑定 MODEL: PlatFormRole.java @Entity @Table(name = "dsm_ROLE") public class PlatformRole extends DsmObject { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column private Integer role_id; @Column private String role_nam