Spring MVC 是 Spring 给我们提供的⼀个⽤于简化 Web 开发的框架

2.1 SpringMVC简介

2.1.1 MVC体系结构

经典三层&mvc模式.png
三层架构
我们的开发架构⼀般都是基于两种形式,⼀种是 C/S 架构,也就是客户端/服务器;另⼀种是 B/S 架构
,也就是浏览器服务器。在 JavaEE 开发中,⼏乎全都是基于 B/S 架构的开发。那么在 B/S 架构中,系
统标准的三层架构包括:表现层、业务层、持久层。三层架构解释:

  • 表现层:也就是我们常说的web 层。它负责接收客户端请求,向客户端响应结果,通常客户端使⽤http 协议请求web 层,web 需要接收 http 请求,完成 http 响应。
  • 业务层:也就是我们常说的 service 层。它负责业务逻辑处理,和我们开发项⽬的需求息息相关。web 层依赖业务层,但是业务层不依赖 web 层。
  • 持久层:也就是我们是常说的 dao 层。负责数据持久化,包括数据层即数据库和数据访问层,数据库是对数据进⾏持久化的载体,数据访问层是业务层和持久层交互的接⼝,业务层需要通过数据访问层将数据持久化到数据库中。通俗的讲,持久层就是和数据库交互,对数据库表进⾏增删改查的。

    2.1.2 MVC是什么

  1. SpringMVC 全名叫 Spring Web MVC,是⼀种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级Web 框架,属于 SpringFrameWork 的后续产品。Spring MVC 本质可以认为是对servlet的封装,简化了我们serlvet的开发
  2. 作⽤:1)接收处理前端的http请求 2)返回响应,跳转⻚⾯
  3. MVC和原生Servlet的区别
  4. springmvc模式和原生servlet模式区别.png

    2.2 MVC的主要工作流程

    开发过程:

  5. 配置DispatcherServlet前端控制器

  6. 开发处理具体业务逻辑的Handler(@Controller、@RequestMapping)
  7. xml配置⽂件配置controller扫描,配置springmvc三⼤件
  8. 将xml⽂件路径告诉springmvc(DispatcherServlet)

2. Spring MVC简介与应用 - 图3

流程说明

  1. 第一步:⽤户发送请求⾄前端控制器DispatcherServlet
  2. 第⼆步:DispatcherServlet收到请求调⽤HandlerMapping处理器映射器
  3. 第三步:处理器映射器根据请求Url找到具体的Handler(后端控制器),⽣成处理器对象及处理器拦截器(如果 有则⽣成)⼀并返回DispatcherServlet
  4. 第四步:DispatcherServlet调⽤HandlerAdapter处理器适配器去调⽤Handler
  5. 第五步:处理器适配器执⾏Handler
  6. 第六步:Handler执⾏完成给处理器适配器返回ModelAndView
  7. 第七步:处理器适配器向前端控制器返回 ModelAndView,ModelAndView 是SpringMVC 框架的⼀个底层对 象,包括 Model 和 View
  8. 第⼋步:前端控制器请求视图解析器去进⾏视图解析,根据逻辑视图名来解析真正的视图。
  9. 第九步:视图解析器向前端控制器返回View
  10. 第⼗步:前端控制器进⾏视图渲染,就是将模型数据(在 ModelAndView 对象中)填充到 request 域
  11. 第⼗⼀步:前端控制器向⽤户响应结果

    2.3 MVC的九大组件

  12. HandlerMapping(处理器映射器):HandlerMapping 是⽤来查找 Handler 的,也就是处理器,具体的表现形式可以是类,也可以是⽅法。⽐如,标注了@RequestMapping的每个⽅法都可以看成是⼀个Handler。Handler负责具体实际的请求处理,在请求到达后,HandlerMapping 的作⽤便是找到请求相应的处理器Handler 和 Interceptor。存储了url和handler的映射关系。

  13. HandlerAdapter(处理器适配器):HandlerAdapter 是⼀个适配器。因为 Spring MVC 中 Handler 可以是任意形式的,只要能处理请求即可。但是把请求交给 Servlet 的时候,由于 Servlet 的⽅法结构都是doService(HttpServletRequest req,HttpServletResponse resp)形式的,要让固定的 Servlet 处理⽅法调⽤ Handler 来进⾏处理,便是 HandlerAdapter 的职责。
  14. ViewResolver(视图解析器):⽤于将String类型的视图名和Locale解析为View类型的视图,只有⼀个resolveViewName()⽅法。从⽅法的定义可以看出,Controller层返回的String类型视图名viewName 最终会在这⾥被解析成为View。View是⽤来渲染⻚⾯的,也就是说,它会将程序返回的参数和数据填⼊模板中,⽣成html⽂件。ViewResolver 在这个过程主要完成两件事情:ViewResolver 找到渲染所⽤的模板(第⼀件⼤事)和所⽤的技术(第⼆件⼤事,其实也就是找到视图的类型,如JSP)并填⼊参数。默认情况下,Spring MVC会⾃动为我们配置⼀个InternalResourceViewResolver,是针对 JSP 类型视图的。
  15. HandlerExceptionResolver:HandlerExceptionResolver ⽤于处理 Handler 产⽣的异常情况。它的作⽤是根据异常设置ModelAndView,之后交给渲染⽅法进⾏渲染,渲染⽅法会将 ModelAndView 渲染成⻚⾯。
  16. RequestToViewNameTranslator:RequestToViewNameTranslator 组件的作⽤是从请求中获取 ViewName.因为 ViewResolver 根据ViewName 查找 View,但有的 Handler 处理完成之后,没有设置 View,也没有设置 ViewName,便要通过这个组件从请求中查找 ViewName。
  17. LocaleResolver:ViewResolver 组件的 resolveViewName ⽅法需要两个参数,⼀个是视图名,⼀个是 Locale。LocaleResolver ⽤于从请求中解析出 Locale,⽐如中国 Locale 是 zh-CN,⽤来表示⼀个区域。这个组件也是 i18n 的基础。
  18. ThemeResolver:ThemeResolver 组件是⽤来解析主题的。主题是样式、图⽚及它们所形成的显示效果的集合。Spring MVC 中⼀套主题对应⼀个 properties⽂件,⾥⾯存放着与当前主题相关的所有资源,如图⽚、CSS样式等。创建主题⾮常简单,只需准备好资源,然后新建⼀个“主题名.properties”并将资源设置进去,放在classpath下,之后便可以在⻚⾯中使⽤了。SpringMVC中与主题相关的类有ThemeResolver、ThemeSource和Theme。ThemeResolver负责从请求中解析出主题名,ThemeSource根据主题名找到具体的主题,其抽象也就是Theme,可以通过Theme来获取主题和具体的资源。
  19. MultipartResolver:MultipartResolver ⽤于上传请求,通过将普通的请求包装成MultipartHttpServletRequest 来实现。MultipartHttpServletRequest 可以通过 getFile() ⽅法 直接获得⽂件。如果上传多个⽂件,还可以调⽤ getFileMap()⽅法得到Map这样的结构,MultipartResolver 的作⽤就是封装普通的请求,使其拥有⽂件上传的功能。
  20. FlashMapManager:FlashMap ⽤于重定向时的参数传递,⽐如在处理⽤户订单时候,为了避免重复提交,可以处理完post请求之后重定向到⼀个get请求,这个get请求可以⽤来显示订单详情之类的信息。这样做虽然可以规避⽤户重新提交订单的问题,但是在这个⻚⾯上要显示订单的信息,这些数据从哪⾥来获得呢?因为重定向时么有传递参数这⼀功能的,如果不想把参数写进URL(不推荐),那么就可以通过FlashMap来传递。只需要在重定向之前将要传递的数据写⼊请求(可以通过ServletRequestAttributes.getRequest()⽅法获得)的属性OUTPUT_FLASH_MAP_ATTRIBUTE中,这样在重定向之后的Handler中Spring就会⾃动将其设置到Model中,在显示订单信息的⻚⾯上就可以直接从Model中获取数据。FlashMapManager 就是⽤来管理 FalshMap 的。

    2.4 MVC的数据输出机制

    ```java @Controller @RequestMapping(“test”) public class TestController{

    public String test1(ModelMap modelMap) {

    1. modelMap.addAttribute("test","1");
    2. return "success";

    }

    public String test1(Modle model) {

    1. model.addAttribute("test","1");
    2. return "success";

    }

    public String test1(Map map) {

    1. map.put("test","1");
    2. return "success";

    }

}

  1. 1. Spring MVChandler的方法中传入ModelMapModelMap参数,并向这些参数中保存数据,实际是保存到了请求域当中,都可以在页面获取得到。
  2. 2. 这三个参数运行时的具体类型都是BindingAwareModelMap,相当于给BindingAwareModelMap中保存数据都会放在请求域中。
  3. 3. 三个参数的关系
  4. - Mapjdk的接口,ModelSpring的接口
  5. - ModelMap实现了Map接口
  6. - BindingAwareModelMap继承了ExtendedMapExtendMap继承了ModelMap,实现了Model接口
  7. - 所以这三个参数底层都是一样的
  8. <a name="ShMUg"></a>
  9. # 2.5 请求参数绑定
  10. <a name="SSYNl"></a>
  11. ## 2.5.1 参数绑定介绍
  12. 1. 原生Servlet的参数传递:http请求传输一个整型参数,原生servlet来接收
  13. - String ageStr = request.getParameter("age");
  14. - int age = Integer.parseInt(ageStr);
  15. 2. Spring MVC是对Servlet的封装,所以简化了很多Servlet的操作,其中 也包括了接收参数。
  16. 3. Spring MVC接收一个整型参数直接在Hanlder的方法中声明形参即可。
  17. ```java
  18. @RequestMapping("xxx")
  19. public String handle(Integer age) {
  20. System.out.println(age);
  21. }
  1. 参数绑定:取出参数值绑定到handler⽅法的形参上

    2.5.2 参数绑定详情

  2. 默认⽀持 Servlet API 作为⽅法参数:当需要使⽤HttpServletRequest、HttpServletResponse、HttpSession等原⽣servlet对象时,直接在handler⽅法中形参声明使⽤即可。

    1. @RequestMapping("/handle01")
    2. public ModelAndView handle01(HttpServletRequest request,
    3. HttpServletResponse response,HttpSession session) {
    4. String id = request.getParameter("id");
    5. Date date = new Date();
    6. ModelAndView modelAndView = new ModelAndView();
    7. modelAndView.addObject("date",date);
    8. modelAndView.setViewName("success");
    9. return modelAndView;
    10. }
  3. 绑定简单数据类型参数(八种基本类型及其包装类型),只需要直接声明形参即可(形参参数名和传递的参数名要保持⼀致,建议 使⽤包装类型,当形参参数名和传递参数名不⼀致时可以使⽤@RequestParam注解进⾏⼿动映射)

    1. @RequestMapping("/handle02")
    2. public ModelAndView handle02(@RequestParam("ids") Integer id,Boolean
    3. flag) {
    4. Date date = new Date();
    5. ModelAndView modelAndView = new ModelAndView();
    6. modelAndView.addObject("date",date);
    7. modelAndView.setViewName("success");
    8. return modelAndView;
    9. }
  4. 绑定Pojo类型参数:接收pojo类型参数,直接形参声明即可,类型就是Pojo的类型,形参名⽆所谓。但是要求传递的参数名必须和Pojo的属性名保持⼀致。

    2.6 Restful风格请求支持

  5. 什么是Restful

  • Restful 是⼀种 web 软件架构⻛格,它不是标准也不是协议,它倡导的是⼀个资源定位及资源操作的⻛格。
  • 它本身并没有什么实⽤性,其核⼼价值在于如何设计出符合 REST ⻛格的⽹络接⼝。
  1. Restful 的优点
  • 它结构清晰、符合标准、易于理解、扩展⽅便,所以正得到越来越多⽹站的采⽤。
  1. RESTful 的示例
  • get 查询,获取资源
  • post 增加,新建资源
  • put 更新
  • delete 删除资源
  • rest⻛格带来的直观体现:就是传递参数⽅式的变化,参数可以在uri中了
  • 示例:/account/1 HTTP GET :得到 id = 1 的 account

    /account/1 HTTP DELETE:删除 id = 1 的 account
    /account/1 HTTP PUT:更新 id = 1 的 account

    2.7 AJAX json交互

  1. 交互
  • 前端到后台:前端ajax发送json格式字符串,后台直接接收为pojo参数,使⽤注解@RequstBody
  • 后台到前端:后台直接返回pojo对象,前端直接接收为json对象或者字符串,使⽤注解@ResponseBody
  1. 什么是 Json
    • Json是⼀种与语⾔⽆关的数据交互格式,就是⼀种字符串,只是⽤特殊符号{}内表示对象、[]内表示数

组、””内是属性或值、:表示后者是前者的值

  • {“name”: “Michael”}可以理解为是⼀个包含name为Michael的对象
  • [{“name”: “Michael”},{“name”: “Jerry”}]就表示包含两个对象的数组
    1. spring mvc和Json的交互
    • 所需jar包 ```xml com.fasterxml.jackson.core jackson-core 2.9.0
com.fasterxml.jackson.core jackson-databind 2.9.0

com.fasterxml.jackson.core jackson-annotations 2.9.0

  1. - 示例代码:
  2. - 前端jsp⻚⾯及js代码
  3. ```html
  4. <div>
  5. <h2>Ajax json交互</h2>
  6. <fieldset>
  7. <input type="button" id="ajaxBtn" value="ajax提交"/>
  8. </fieldset>
  9. </div>
  1. $(function () {
  2. $("#ajaxBtn").bind("click",function () {
  3. // 发送ajax请求
  4. $.ajax({
  5. url: '/demo/handle07',
  6. type: 'POST',
  7. data: '{"id":"1","name":"李四"}',
  8. contentType: 'application/json;charset=utf-8',
  9. dataType: 'json',
  10. success: function (data) {
  11. alert(data.name);
  12. }
  13. })
  14. })
  15. })
  • 后台Handler⽅法
    1. @RequestMapping("/handle07")
    2. @ResponseBody
    3. // 添加@ResponseBody之后,不再⾛视图解析器那个流程,⽽是等同于response直接输出
    4. // 数据
    5. public User handle07(@RequestBody User user) {
    6. // 业务逻辑处理,修改name为张三丰
    7. user.setName("张三丰");
    8. return user;
    9. }