38-SpringMVC

38-SpringMVC-qianfeng-笔记


文章目录

  • 38-SpringMVC-qianfeng-笔记
  • 一、SpringMVC概述
    • ①:SpringMVC优势
    • ②:SpringMVC本质工作
  • 二、SpringMVC框架部署
    • ①:创建Web工程
      • 01. 创建步骤
      • 02. 添加依赖
      • 03. 创建SpringMVC配置文件
      • 04. 在web.xml中配置SpringMVC的前控制器
    • 三、SpringMVC框架使用
    • ①:创建控制器
      • 01. 创建控制器类
      • 02. 在控制器类中定义处理请求的方法
      • 03. 访问
    • ②:静态资源配置
      • 00. 创建前端页面
      • 01. /* 和 /的区别
      • 02. 静态资源放行配置
    • ③:前端提交数据到控制器
      • 01.设置表单提交路径
      • 02.表单提交
      • 03. URL提交
      • 04. AJAX提交
    • ④:控制器接收前端提交的数据
      • 01.请求行传值
      • 02. 请求头传值
      • 03. 请求行和请求头同时传值
      • 04.请求体传值
        • 1.方式一(request输入流读数据)
        • 2. 方式二(使用@RequestBody)
    • ⑤:控制器响应前端请求
      • 01. 控制器响应同步请求
        • 1. 返回类型为String
        • 2.返回类型为ModelAndView
      • 02. 控制器响应异步请求
        • 1. **使用response中的输出流进行响应**
        • 2.直接在控制器方法返回响应的对象
    • ⑥:控制器响应同步请求的数据传递
      • 01. 返回类型为String
      • 02. 返回类型ModelAndView
    • ⑦:中文乱码问题
      • 01. 前端编码
      • 02.设置服务器编码设置
      • 03. 后端(SpringMVC)编码设置
      • 04. 测试
  • 四、SpringMVC的请求处理流程
    • ①:请求处理流程
    • ②:SpringMVC的核心组件
    • ③:处理器映射器
    • ④:视图解析器
  • 五、日期格式处理
    • ①:使用对象来接收数据
    • ②:日期格式处理
      • 01. 自定义日期转换器
      • 02. 配置自定义日期转换器
  • 六、文件上传
    • ①:SpringMvc框架部署
    • ②:案例准备
      • 01. 创建index.jsp(首页面)
      • 02. 创建book-add.jsp(图书添加页面)
      • 03.创建tips.jsp页面
      • 04.设置index.jsp为默认页面
      • 05. 创建BookConverter类
    • ③:文件上传实现
      • 01.创建实体类
      • 02. 前端提交文件
      • 03.控制器接收数据和文件
      • 04.保存数据(图片)
  • 七、 文件下载
    • ①:显示文件列表
    • ②:文件下载实现
  • 八、统一异常处理
    • ①:HTTP异常状态统一处理
    • ②:Java代码异常的统一处理
      • 01. 基于Servlet
      • 02. SpringMVC处理
  • 九、拦截器
    • ①:拦截器介绍
    • ②:自定义拦截器
      • 01.创建拦截器
      • 02. 配置拦截器
      • 03.添加控制器方法
    • ③:拦截器链
  • 十、SSM整合
    • ①:创建Web项目
      • 01. 创建web工程
      • 02. 添加web项目依赖
      • 03.配置Tomcat运行环境
    • ②:部署MyBatis
      • 01. 添加MyBatis依赖
      • 02. 创建mybatis-config.xml
    • ③:部署Spring、SpringMVC
      • 01.添加依赖
      • 02.创建Spring配置(多个文件分开配置)
    • ④:配置SpringMvc前端控制器
    • ⑤:整合配置(IOC)
      • 01.导入mybatis-spring依赖
      • 02.配置druid连接池
      • 03.配置SqlSessionFactory
      • 04.配置MapperScannerConfigurer
    • ⑥:整合配置(AOP)
    • ⑦:整合测试
      • 01.完成User的查询操作
      • 02. 对DAO单元测试
      • 03.对Service单元测试
    • ⑧:整合Controller
  • 十一 纯注解开发(补)
    • ①:使用注解开发(入门案例)
    • ②:bean加载控制
    • ③:PostMan工具
    • ④:postman发送get和post请求
    • ⑤post发送json数据
      • 01. 集合参数(Json)
      • 02. pojo参数(Json)
      • 03. pojo集合参数
      • 04. 日期参数
    • ⑤:REST风格
      • 01. 入门案例
      • 02.RESTful快速开发
    • ⑥:基于RESTful页面数据交互
      • 01.数据准备
      • 02. 放行静态资源
  • 十二、纯注解SSM整合(补)
    • ①:整合配置
    • ②:功能模块开发
    • ③:接口测试
    • ④:事务管理
    • ⑤:乱码处理
    • ⑥:表现层与前端数据协议实现
    • ⑦:异常处理
      • 01. 异常处理器
      • 02. 异常处理方案
    • ⑧:放行静态资源
  • 十三、拦截器
    • ①:拦截器入门
    • ②:简化以上开发
    • ③:拦截器参数


一、SpringMVC概述

Spring MVC是由Spring官方提供的基于MvC设计理念的web框架。
SpringMVC是基于Servlet封装的用于实现MWC控制的框架,实现前端和服务端的交互。

①:SpringMVC优势

  • 严格遵守了MVC分层思想
  • 采用了松耦合、插件式结构;相比较于我们封装的BaseServlet以及其他的一些MVC框架来说更灵活、更具扩展性
  • SpringMVC是基于Spring的扩展、提供了一套完善的MVC注解
  • SpringMVC在数据绑定、视图解析都提供了多种处理方式,可灵活配置
  • SpringMVC对RESTful URL设计方法提供了良好的支持

②:SpringMVC本质工作

  • 接收并解析请求
  • 处理请求
  • 数据渲染、响应请求

二、SpringMVC框架部署

①:创建Web工程

01. 创建步骤

1.使用骨架
38-SpringMVC_第1张图片38-SpringMVC_第2张图片 38-SpringMVC_第3张图片38-SpringMVC_第4张图片

38-SpringMVC_第5张图片

2. 补全项目结构
38-SpringMVC_第6张图片

02. 添加依赖

  • spring-context
  • spring-aspects
  • spring-jdbc
  • spring-web
  • spring-webmvc
  • spring-test
3. 添加依赖
<dependency>
  <groupId>org.springframeworkgroupId>
  <artifactId>spring-contextartifactId>
  <version>5.3.18version>
dependency>
<dependency>
  <groupId>org.springframeworkgroupId>
  <artifactId>spring-aspectsartifactId>
  <version>5.3.18version>
dependency>
<dependency>
  <groupId>org.springframeworkgroupId>
  <artifactId>spring-jdbcartifactId>
  <version>5.3.18version>
dependency>

<dependency>
  <groupId>org.springframeworkgroupId>
  <artifactId>spring-webartifactId>
  <version>5.3.18version>
dependency>

<dependency>
  <groupId>org.springframeworkgroupId>
  <artifactId>spring-webmvcartifactId>
  <version>5.3.18version>
dependency>

<dependency>
  <groupId>org.springframeworkgroupId>
  <artifactId>spring-testartifactId>
  <version>5.3.18version>
  <scope>testscope>
dependency>

03. 创建SpringMVC配置文件

  • 在resources目录下创建名为spring-servlet.xml的文件
  • 添加MVC命名空间

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop.xsd 
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc.xsd    
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">
    

    <context:annotation-config/>
    
    <mvc:annotation-driven />

    
    <context:component-scan base-package="com" />
    
beans>

04. 在web.xml中配置SpringMVC的前控制器

SpringMVC提供了一个名为DispatcherServlet的类(SpringMVCi前端控制器),用于拦截用户请求交由
SpringMVC处理

<servlet>
  <servlet-name>SpringMVCservlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>

  <init-param>
    <param-name>contextConfigLocationparam-name>
    <param-value>classpath:spring-servlet.xmlparam-value>
  init-param>

  <load-on-startup>1load-on-startup>
servlet>

<servlet-mapping>
  <servlet-name>SpringMVCservlet-name>
  <url-pattern>/*url-pattern>
servlet-mapping>
38-SpringMVC_第7张图片

三、SpringMVC框架使用

在SpringMVC中,我们把接收用户请求、处理用户请求的类称之为Controlelr(控制器)

①:创建控制器

01. 创建控制器类

  • 创建一个名为com.qfedu.controllers的包(包需要在Spring注解扫描的范围内)
  • 创建一个类(无需做任何的继承和实现)
  • 在类上添加@Controller注解声明此类为SpringMVC的控制器
  • 在类上添加@RequestMapping("url")声明此控制器类的请求url
@Controller
@RequestMapping("/book")
public class BookController {

}

02. 在控制器类中定义处理请求的方法

  • 在一个控制器类中可以定于多个方法处理不同的请求
  • 在每个方法上添加@RequestMapping("url")用于声明当前方法请求的url
@Controller
@RequestMapping("/book")
public class BookController {

    @RequestMapping("/add")
    public void add(){
        System.out.println("**********Book add************");
    }
    @RequestMapping("/list")
    public void list(){
        System.out.println("**********Book list************");
    }
}

03. 访问

  • http://localhost/01_springMVC_demo1/book/add

  • http://localhost/01_springMVC_demo1/book/list

38-SpringMVC_第8张图片
注意:若无法访问 检查Tomcat路径是否修改
38-SpringMVC_第9张图片38-SpringMVC_第10张图片

②:静态资源配置

00. 创建前端页面

  • book-add.jsp
<%@page contentType="text/html;charset=UTF-8" language="java" %>

<html>
<head>
    <title>添加图书title>
head>
<body>
<h3>添加图书h3>
<form action="" method="post">
    <p>图书名称:<input type="text"/>p>
    <p>图书作者:<input type="text"/>p>
    <p>图书价格:<input type="text"/>p>
    <p><input type="submit" value="提交"/>p>
form>
body>
html>

38-SpringMVC_第11张图片

01. /* 和 /的区别

  • /*拦截所有的HTTP请求,包括.jsP的请求,都做为控制器类的请求路径来处理
  • /拦截所有的HTTP请求,但不包括,jsp的请求,不会放行静态资源的请求(html/css/js/图片)
1. 使用/*
38-SpringMVC_第12张图片
2. 使用/
38-SpringMVC_第13张图片
3. 添加静态资源css样式后在访问
38-SpringMVC_第14张图片

02. 静态资源放行配置

在springMVCl的配置文件,添加如下静态资源放行的配置


    <mvc:resources mapping="/css/**" location="css/"/>
    <mvc:resources mapping="/js/**" location="js/"/>
    <mvc:resources mapping="/imgs/**" location="imgs/"/>
    <mvc:resources mapping="/pages/**" location="pages/"/>
38-SpringMVC_第15张图片 38-SpringMVC_第16张图片

③:前端提交数据到控制器

01.设置表单提交路径

book-add,jsp表单的action属性设置控制器类的url和对应方法的url的组合路径
38-SpringMVC_第17张图片

02.表单提交

  • 表单提交:输入框需要提供name属性,SpringMVC控制器是通过name属性取值的
<body>
<h3>添加图书h3>
<form action="book/add" method="post">
    <p>图书名称:<input type="text" name="bookName"/>p>
    <p>图书作者:<input type="text" name="bookAuthor"/>p>
    <p>图书价格:<input type="text" name="bookPrice"/>p>
    <p><input type="submit" value="提交"/>p>
form>
body>

03. URL提交

04. AJAX提交

  • AJAX提交:请求行、请求头、请求体都可以用来传值
<script type="text/javascript" src="js/jquery-3.6.0.min.js">script>
<input type="button" value="ajax提交" id="btn1"/>
<script type="text/javascript">
    $("#btn1").click(function (){
        var obj = {};
        obj.bookName = "Java";
        obj.bookAuthor = "张三";
        obj.bookPrice = 9.99;

        $.ajax({
            url:"book/add",
            type: "post",
            headers:{},
            contentType:"application/json",
            data:obj,
            success:function (res){
                console.log(res)
            }
        });
    });
script>
38-SpringMVC_第18张图片

④:控制器接收前端提交的数据

01.请求行传值

  • 表单提交
  • URL提交
  • $.ajax()请求的url传值
  • $.post()/$.get()中的{}传值
  • @RequestParam注解用于接收请求行传递的数据

前端提交数据

<form action="book/add" method="post">
    <p>图书名称:<input type="text" name="bookName"/>p>
    <p>图书作者:<input type="text" name="bookAuthor"/>p>
    <p>图书价格:<input type="text" name="bookPrice"/>p>
    <p><input type="submit" value="提交"/>p>
form>

控制器接收数据

    // 接收请求行数据
    @RequestMapping("/add")
    public void add(@RequestParam("bookName") String bookName,
                    @RequestParam("bookAuthor") String bookAuthor,
                    @RequestParam("bookPrice") String bookPrice){
        System.out.println("**********Book add************");
        System.out.println("bookName = " + bookName);
        System.out.println("bookAuthor = " + bookAuthor);
        System.out.println("bookPrice = " + bookPrice);
    }

38-SpringMVC_第19张图片

注意:如果控制器方法中接收数据的参数名与请求行传值的key一致
则@RequestParami注解可省略
38-SpringMVC_第20张图片38-SpringMVC_第21张图片

02. 请求头传值

  • ajax封装请求头数据

前端代码

<input type="button" value="ajax提交" id="btn1"/>
<script type="text/javascript" src="js/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
    $("#btn1").click(function () {
        $.ajax({
            url: "book/list",
            type: "post",
            headers: {
                token: "My name is Coke"
            },
            success: function (res) {
                console.log(res)
            }
        });
    });
</script>)

后端代码

    @RequestMapping("/list")
    public void list(@RequestHeader("token") String token){
        System.out.println("**********Book list************");
        System.out.println(token);
    }

38-SpringMVC_第22张图片

03. 请求行和请求头同时传值

前端代码

<input type="button" value="ajax提交" id="btn1"/>
<script type="text/javascript" src="js/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
    $("#btn1").click(function () {
        $.ajax({
            url: "book/add?bookName=Java&bookAuthor=Coke&bookPrice=9.9",
            type: "post",
            headers: {
                token: "My name is Coke"
            },
            success: function (res) {
                console.log(res)
            }
        });
    });
</script>

后端代码

    // 接收请求行数据
    @RequestMapping("/add")
    public void add(String bookName,
                    String bookAuthor,
                    String bookPrice,
                    @RequestHeader("token") String token){
        System.out.println("**********Book add************");
        System.out.println("bookName = " + bookName);
        System.out.println("bookAuthor = " + bookAuthor);
        System.out.println("bookPrice = " + bookPrice);
        System.out.println("token = " + token);
    }
38-SpringMVC_第23张图片

04.请求体传值

1.方式一(request输入流读数据)

  • ajax封装请求体数据

前端代码

<input type="button" value="ajax提交" id="btn1"/>
<script type="text/javascript" src="js/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
    $("#btn1").click(function (){
        var obj = {};
        obj.bookName = "Java";
        obj.bookAuthor = "Coke";
        obj.bookPrice = 9.99;

        $.ajax({
            url:"book/update",
            type: "post",
            contentType:"application/json",
            data:obj,
            success:function (res){
                console.log(res)
            }
        });
    });
</script>

后端代码

    @RequestMapping("/update")
    public void update(HttpServletRequest request){
        System.out.println("**********Book update************");
        try {
            // 使用request的输入流接收请求体数据
            ServletInputStream is = request.getInputStream();
            StringBuffer buffer = new StringBuffer();
            byte[] bs = new byte[100];
            int len = -1;
            while ((len = is.read(bs)) != -1) {
                String s = new String(bs, 0, len);
                buffer.append(s);
            }
            System.out.println("buffer.toString() = " + buffer.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
在这里插入图片描述

2. 方式二(使用@RequestBody)

  • 添加依赖(@RequestBody需要将json格式数据转换成java对象)

<dependency>
  <groupId>com.fasterxml.jackson.coregroupId>
  <artifactId>jackson-databindartifactId>
  <version>2.13.3version>
dependency>
1. 创建Book类并提供get set 等方法
38-SpringMVC_第24张图片
2. 前端代码
<input type="button" value="ajax提交" id="btn1"/>
<script type="text/javascript" src="js/jquery-3.6.0.min.js">script>
<script type="text/javascript">
    $("#btn1").click(function (){
        var obj = {};
        obj.bookName = "Java";
        obj.bookAuthor = "Coke";
        obj.bookPrice = 9.99;
        var s = JSON.stringify(obj)
        $.ajax({
            url:"book/update",
            type: "post",
            contentType:"application/json",
            data:s,
            success:function (res){
                console.log(res)
            }
        });
    });
script>
38-SpringMVC_第25张图片
3. 后端代码
    @RequestMapping("/update")
    public void update(@RequestBody Book book){
        System.out.println("**********Book update************");
        System.out.println(book);
    }

38-SpringMVC_第26张图片

⑤:控制器响应前端请求

01. 控制器响应同步请求

  • 同步请求:form、超链接

处理同步请求的方法的返回类型定义为String或者ModelAndView,以实现页面的跳转

1. 返回类型为String

1. 转发

1. 添加跳转后tips.jsp界面
38-SpringMVC_第27张图片
2. 后端代码
    // 接收请求行数据
    @RequestMapping("/add")
    public String add(String bookName, String bookAuthor, String bookPrice){
        System.out.println("**********Book add************");
        System.out.println("bookName = " + bookName);
        System.out.println("bookAuthor = " + bookAuthor);
        System.out.println("bookPrice = " + bookPrice);
        return "/tips.jsp";
    }
3. 测试
38-SpringMVC_第28张图片

2. 重定向

    // 接收请求行数据
    @RequestMapping("/add")
    public String add(String bookName, String bookAuthor, String bookPrice){
        System.out.println("**********Book add************");
        System.out.println("bookName = " + bookName);
        System.out.println("bookAuthor = " + bookAuthor);
        System.out.println("bookPrice = " + bookPrice);
        return "redirect:/tips.jsp";
    }

2.返回类型为ModelAndView

1. 转发

    // 接收请求行数据
    @RequestMapping("/add")
    public ModelAndView add(String bookName, String bookAuthor, String bookPrice){
        System.out.println("**********Book add************");
        System.out.println("bookName = " + bookName);
        System.out.println("bookAuthor = " + bookAuthor);
        System.out.println("bookPrice = " + bookPrice);
        ModelAndView modelAndView = new ModelAndView("/tips.jsp");
        return modelAndView;
    }

2. 重定向

    // 接收请求行数据
    @RequestMapping("/add")
    public ModelAndView add(String bookName, String bookAuthor, String bookPrice){
        System.out.println("**********Book add************");
        System.out.println("bookName = " + bookName);
        System.out.println("bookAuthor = " + bookAuthor);
        System.out.println("bookPrice = " + bookPrice);
        ModelAndView modelAndView = new ModelAndView("redirect:/tips.jsp");
        return modelAndView;
    }

02. 控制器响应异步请求

异步请求:ajax请求

1. 使用response中的输出流进行响应

  • 控制器方法的返回类型为void
  • 控制器方法添加HttpServletResponse response参数
  • 在方法中通过response获取输出流,使用流响应ajax清求
1. 前端代码
<input type="button" value="ajax提交" id="btn1"/>
<script type="text/javascript" src="js/jquery-3.6.0.min.js">script>
<script type="text/javascript">
    $("#btn1").click(function (){
        var obj = {};
        obj.bookName = "Java";
        obj.bookAuthor = "Coke";
        obj.bookPrice = 9.99;
        var s = JSON.stringify(obj)
        $.ajax({
            url:"book/update",
            type: "post",
            contentType:"application/json",
            data:s,
            success:function (res){
                console.log(res)
            }
        });
    });
script>
2. 后端代码
    @RequestMapping("/update")
    public void update(@RequestBody Book book, HttpServletResponse response) throws IOException {
        System.out.println("**********Book update************");
        // 使用ObjectMapper将对象转换成JSON格式字符串
        String s = new ObjectMapper().writeValueAsString(book);
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");
        PrintWriter out = response.getWriter();
        out.println(s);
        out.flush();
        out.close();
    }
3. 测试
38-SpringMVC_第29张图片

2.直接在控制器方法返回响应的对象

  • 控制器方法的返回类型设置为响应给ajax请求的对象类型
  • 在控制器方法前添加@ResponseBody注解,将返回的对象转换成JSON响应给ajax请求
1. 后端代码(前端代码无修改)
    @RequestMapping("/update")
    @ResponseBody
    public List<Book> update() {
        System.out.println("**********Book update************");
        ArrayList<Book> books = new ArrayList<>();
        books.add(new Book(1,"Java","Coke",9.9));
        books.add(new Book(2,"Linux","KangKang",9.99));
        return books;
    }
38-SpringMVC_第30张图片

⑥:控制器响应同步请求的数据传递

对于同步请求的转发响应,我们可以传递参数到转发的页面

01. 返回类型为String

1. 前端代码
38-SpringMVC_第31张图片
2. 后端代码
    //1.在控制器方法中定义一个Mode1类型的参数
    //2.在return页面之前,向model中添加键值对,添加的键值对就会被传递到转发的页面
    @RequestMapping("/add")
    public String add(String bookName, String bookAuthor, Double bookPrice, Model model){
        model.addAttribute("key","value");
        model.addAttribute("book",new Book(1,"Java","Coke",9.9));
        return "/tips.jsp";
    }
    //除了使用Model对象传值外,还可以直接使用HttpServletRequest对象
    @RequestMapping("/add")
    public String add(String bookName, String bookAuthor, Double bookPrice, HttpServletRequest request){
        request.setAttribute("key","value");
        request.setAttribute("book",new Book(1,"Java","Coke",9.9));
        return "/tips.jsp";
    }
3. 测试
38-SpringMVC_第32张图片

02. 返回类型ModelAndView

    @RequestMapping("/add")
    public ModelAndView add(String bookName, String bookAuthor, Double bookPrice){
        ModelAndView model = new ModelAndView("/tips.jsp");
        model.addObject("key","value");
        model.addObject("book",new Book(1,"Java","Coke",9.9));
        return model;
    }

⑦:中文乱码问题

01. 前端编码

  • JSP 页面编码设置
<%@page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
  • HTML页面编码设置
<meta charset="UTF-8">

02.设置服务器编码设置

<Connector port="80" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" URIEncoding="UTF-8"/>
tomcat/conf/server.xml
38-SpringMVC_第33张图片

03. 后端(SpringMVC)编码设置

    <filter>
        <filter-name>EncodingFilterfilter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
        <init-param>
            <param-name>encodingparam-name>
            <param-value>utf-8param-value>
        init-param>
        <init-param>
            <param-name>forceEncodingparam-name>
            <param-value>trueparam-value>
        init-param>
    filter>
<filter-mapping>
    <filter-name>EncodingFilterfilter-name>
    <url-pattern>/*url-pattern>
filter-mapping>
38-SpringMVC_第34张图片

04. 测试

中文乱码已解决
38-SpringMVC_第35张图片

四、SpringMVC的请求处理流程

①:请求处理流程

SpringMVC通过前端控制器(DispatcherServlet)拦截并处理用户请求的

38-SpringMVC_第36张图片

②:SpringMVC的核心组件

  • DispatcherServlet前端控制器、总控制器
    • 作用:接收请求, 协同各组件工作、响应请求
  • HandlerMapping 处理器映射(可配置)
    • 作用:负责根据用户请求的URL找到对应的Handler(Controller)
  • Handler Adapter处理器适配器
    • 作用:按照处理器映射器解析的用户请求的调用链,通过适配器模式完成Handler的调用
  • Handler处理器/控制器
    • 由工程师根据业务的需求进行开发
    • 作用:处理请求
  • ModelAndView视图模型
    • 作用:用于封装处理器返回的数据以及相应的视图
    • ModelAndView = Model + View
  • ViewResolver视图解析器(可配置)
    • 作用:对ModelAndViewi进行解析
  • View视图
    • 作用:完成数据渲染

③:处理器映射器

不同的处理器映射器对UL处理的方式也不相同,使用对应的处理器映射器之后我们的前端请求规则也需要发生相应的变化
SpringMVC提供的处理器映射器:

  • BeanNameUrlHandlerMapping根据控制器的ID访问控制器
  • SimpleUrlHandlerMapping根据控制器配置的URL访问(默认)

配置处理器映射器:

  • SpringMVC的配置文件中通过bean标签声明处理器映射器
  • 配置BeanNameUrlHandlerMapping
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
  • 配置SimpleUrlHandlerMapping
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
            <prop key="/aaa">bookControllerprop>
        props>
    property>
bean>

④:视图解析器

Spring提供了多个视图解析器

  • UrlBasedViewResolver
  • InternalResourceViewResolver
  • UrlBasedViewResolver需要依赖jstl
    • 添加依赖

<dependency>
    <groupId>javax.servletgroupId>
    <artifactId>jstlartifactId>
    <version>1.2version>
dependency>
  • 配置视图解析器 UrlBasedViewResolver
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
   <property name="viewClass" value="com.fasterxml.jackson.annotation.JsonView"/>
   <property name="prefix" value="/"/>
   <property name="suffix" value=".jsp"/>
bean>
  • 配置视图解析器 InternalResourceViewResolver
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/"/>
    <property name="suffix" value=".jsp"/>
bean>
测试
38-SpringMVC_第37张图片

五、日期格式处理

①:使用对象来接收数据

1. 创建一个新的类
38-SpringMVC_第38张图片
2. 修改访问路径
38-SpringMVC_第39张图片
3. 测试(注意:实体类的属性名要和前端输入框的name属性名称一样)
38-SpringMVC_第40张图片

②:日期格式处理

如果前端需要输入日期数据,在控制器中转换成Date对象,SpringMVC要求前端输入的日期格式必须为
yyyy/MM/dd
如果甲方要求日期格式必须为指定的格式,而这个指定格式SpringMVC不接受,该如何处理呢?

  • 自定义日期转换器

01. 自定义日期转换器

1. 添加一个日期属性Data(提供构造器及get set等方法)
38-SpringMVC_第41张图片
2.添加输入框
38-SpringMVC_第42张图片
3. 创建一个自定义日期转换器
// 1.创建一个类实现Converter接口,泛型指定从什么类型转换为什么类型
//  2.实现convert转换方法
public class MyDataConverter implements Converter<String, Date> {
    @Override
    public Date convert(String s) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日");
        Date date = null;
        try {
            date = format.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
}
38-SpringMVC_第43张图片

02. 配置自定义日期转换器

    
    <mvc:annotation-driven conversion-service="converterFactory"/>

    <bean id="converterFactory" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="com.it.utils.MyDataConverter"/>
            set>
        property>
    bean>
38-SpringMVC_第44张图片
测试
38-SpringMVC_第45张图片

六、文件上传

①:SpringMvc框架部署

  • 基于Mavent创建web工程

步骤 略~

  • 添加SpringMVC所需的依赖
    • Spring:context aspects jdbc test web webmvc jackson
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-contextartifactId>
      <version>5.3.18version>
    dependency>
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-aspectsartifactId>
      <version>5.3.18version>
    dependency>

    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-jdbcartifactId>
      <version>5.3.18version>
    dependency>
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-testartifactId>
      <version>5.3.18version>
    dependency>
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-webartifactId>
      <version>5.3.18version>
    dependency>
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-webmvcartifactId>
      <version>5.3.18version>
    dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.coregroupId>
      <artifactId>jackson-databindartifactId>
      <version>2.13.3version>
    dependency>
        <dependency>
      <groupId>javax.servletgroupId>
      <artifactId>javax.servlet-apiartifactId>
      <version>4.0.1version>
    dependency>
  • 创建SpringMVC配置文件
  • 在web.Xml中配置SpringMVC的前端控制器
<servlet>
    <servlet-name>springMVCservlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    <init-param>
        <param-name>contextConfigLocationparam-name>
        <param-value>classpath:spring-servlet.xmlparam-value>
    init-param>
servlet>
    <servlet-mapping>
        <servlet-name>springMVCservlet-name>
        <url-pattern>/url-pattern>
    servlet-mapping>
  • 在web.ml中配置SpringMVC的编码过滤器

  • 配置springmvci静态资源处理策骼

    <context:component-scan base-package="com.it"/>
    <mvc:resources mapping="/js/**" location="/js/"/>
    <mvc:resources mapping="/css/**" location="/css/"/>
    <mvc:resources mapping="/imgs/**" location="/imgs/"/>

②:案例准备

01. 创建index.jsp(首页面)

<%@page contentType="text/html; charset=utf-8" pageEncoding="UTF-8" language="java" %>
<html>
    <body>
        <table width="100%" height="700">
            <tr>
                <td width="200" style="border-right: lightblue 2px solid; background: rgba(255,0,0,0.1)">
                    <ul>
                        <li><a href="book-add.jsp" target="mainFrame">添加图书a> li>
                        <li><a href="">图书列表a>li>
                    ul>
                td>
                <td>
                    <iframe name="mainFrame" width="100%" height="700" frameborder="0">iframe>
                td>
            tr>
            <tr>tr>
        table>
    body>
html>

02. 创建book-add.jsp(图书添加页面)

<%@page contentType="text/html; charset=utf-8" pageEncoding="UTF-8" language="java" %>
<html>
    <body>
        <h4>添加图书信息h4>
        <form action="">
            <p>图书名称:<input type="text" name="">p>
            <p>图书作者:<input type="text" name="">p>
            <p>图书价格:<input type="text" name="">p>
            <p>图书封面:<input type="file" name="">p>
            <p><input type="submit" value="提交">p>
        form>
    body>
html>

03.创建tips.jsp页面

<%@page contentType="text/html; charset=utf-8" pageEncoding="UTF-8" language="java" %>
<html>
    <body>

    body>
html>

04.设置index.jsp为默认页面

  • 在web.xml添加以下配置
    <welcome-file-list>
        <welcome-file>index.jspwelcome-file>
    welcome-file-list>

05. 创建BookConverter类

@Controller
@RequestMapping("/book")
public class BookConverter {

    @RequestMapping("/add")
    public String addBook(){
        System.out.println("*************Book add***************");
        return "/tips.jsp";
    }
}
38-SpringMVC_第46张图片

③:文件上传实现

01.创建实体类

public class Book {
    private int bookId;
    private String bookName;
    private String bookAuthor;
    private double bookPrice;
    private String bookImg;
 }
38-SpringMVC_第47张图片

02. 前端提交文件

  • 表单提交方式必须为post
  • 表单entype属性设置为multipart/form-data
    <body>
        <h4>添加图书信息h4>
        <form action="book/add" method="post" enctype="multipart/form-data">
            <p>图书名称:<input type="text" name="bookName">p>
            <p>图书作者:<input type="text" name="bookAuthor">p>
            <p>图书价格:<input type="text" name="bookPrice">p>
            <p>图书封面:<input type="file" name="imgFile">p>
            <p><input type="submit" value="提交">p>
        form>
    body>

03.控制器接收数据和文件

SpringMVC处理上传文件需要借助于CommonsMultipartResolver文件解析器

  • 添加依赖 commons-io commons-fileupload
    
    <dependency>
      <groupId>commons-iogroupId>
      <artifactId>commons-ioartifactId>
      <version>2.11.0version>
    dependency>
    
    <dependency>
      <groupId>commons-fileuploadgroupId>
      <artifactId>commons-fileuploadartifactId>
      <version>1.3.3version>
    dependency>
  • 在spring-servlet.xml中配置文件解析器
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="10240000"/>
        <property name="maxInMemorySize" value="102400"/>
        <property name="defaultEncoding" value="utf-8"/>
    bean>
  • 空制器接收文件
    • 在处理文件上传的方法中定义一个MultiPartFile类型的对象,就可以接受图片了
38-SpringMVC_第48张图片

04.保存数据(图片)

@Controller
@RequestMapping("/book")
public class BookConverter {

    @RequestMapping("/add")
    public String addBook(Book book, MultipartFile imgFile, HttpServletRequest request) throws IOException {
        System.out.println("*************Book add***************");
        // imgFile 就表示上传的图片
        // 1. 截取上传文件的后缀名,生成新的文件名
        String originalFilename = imgFile.getOriginalFilename();
        String ext = originalFilename.substring(originalFilename.lastIndexOf(".")); // .png
        String filename = System.currentTimeMillis() + ext;

        // 2. 获取imgs目录在服务器中的路径
        String dir = request.getServletContext().getRealPath("imgs");
        String savePath = dir + "/" + filename;

        // 3. 保存文件
        imgFile.transferTo(new File(savePath));

        // 4.将图片的访问路径设置到book对象中
        book.setBookImg("imgs/" + filename);

        // 5.调用service保存book到数据库 略~~
        return "/tips.jsp";
    }
}
1. 在imgs路径下放一个文件,否则空文件不会被加载
38-SpringMVC_第49张图片
2.在tips中添加以下代码(显示数据)
<%@page contentType="text/html; charset=utf-8" pageEncoding="UTF-8" language="java" %>
<html>
    <body>
        图书名称:${book.bookName}
        <hr>
        图书作者:${book.bookAuthor}
        <hr>
        图书价格:${book.bookPrice}
        <hr>
        图书封面:${book.bookImg}
        <hr>
    body>
html>
3. 测试
38-SpringMVC_第50张图片

七、 文件下载

①:显示文件列表

1.在BookConverter类中添加查询方法(查询图片列表)
    @RequestMapping("list")
    @ResponseBody
    public String[] listImgs(HttpServletRequest request){
        // 1. 从imgs目录下获取所有的图片信息
        String path = request.getServletContext().getRealPath("imgs");
        File imgDir = new File(path);
        String[] fileName = imgDir.list();
        return fileName;
    }
2. 添加文件list.jsp
<%@page contentType="text/html; charset=utf-8" pageEncoding="UTF-8" language="java" %>
<html>
<head>
    <title>图书列表title>
head>

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">


<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap-theme.min.css" integrity="sha384-6pzBo3FDv/PJ8r2KRkGHifhEocL+1X2rVCTTkUfGk7/0pbek5mMa1upzvWbrUbOZ" crossorigin="anonymous">


<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous">script>
    <body>
        <h4>图书列表h4>
        <script type="text/javascript" src="js/jquery-3.6.0.min.js">script>
        <script type="text/javascript">
            $.get("book/list",function(res) {
                for (let i = 0; i < res.length; i++) {
                    var fn = res[i];
                    var htmlStr = ""
                    $("#container").append(htmlStr);
                }
            },"json")
        script>

        <div class="row" id="container">

        div>
    body>
html>
3. 修改index.jsp代码
38-SpringMVC_第51张图片
4. 测试
38-SpringMVC_第52张图片

②:文件下载实现

1. BookConverter中添加一个下载方法
@RequestMapping("download")
public void downloadImg(String fname, HttpServletRequest request, HttpServletResponse response) throws Exception {
    // 从imgs目录找到当前文件
    String path = request.getServletContext().getRealPath("imgs");
    String filePath = path + "/" +fname;
    FileInputStream inputStream = new FileInputStream(filePath);
    ServletOutputStream outputStream = response.getOutputStream();

    response.setContentType("application/exe");
    response.addHeader("Content-Disposition","attachment;filename="+fname);

    IOUtils.copy(inputStream,outputStream);
}
38-SpringMVC_第53张图片
2. 在list.jap中添加下载URL
38-SpringMVC_第54张图片

八、统一异常处理

在我们的应用系统运行的过程中,可能由于运行环境、用户操作、资源不足等各方面的原因导致系统出现异常(HTTP状态异常、Exception);如果系统出现了异常,这些异常将会通过浏览器呈现给用户,而这种异常的显示是设有必要,因此我们可以在服务器进行特定的处理一当系统出现异常之后,呈现给用户一个统一的、可读的的异常提示页面。

①:HTTP异常状态统一处理

HTTP Status 404

  • 创建一个用于进行异常提示的页面:404.jsp
<%@page contentType="text/html; charset=utf-8" pageEncoding="UTF-8" language="java" %>
<html>
<head>
head>
    <body>
        您的访问地址有误,请检查....
    body>
html>

  • 在web.xml中进行配置:
    <error-page>
        <error-code>404error-code>
        <location>/404.jsplocation>
    error-page>
测试:(访问一个不存在的地址)
38-SpringMVC_第55张图片

②:Java代码异常的统一处理

01. 基于Servlet

  • 创建异常提示页面:err.jsp
  • 在web.xml中进行配置
<error-page>
    <exception-type>java.lang.NumberFormatExceptionexception-type>
    <location>/err.jsplocation>
error-page>

02. SpringMVC处理

1. 创建一个异常处理类
public class MyExceptionHandler {

    // 空指针异常
    @ExceptionHandler(NullPointerException.class)
    public String nullHandler(){
        return "/err1.jsp";
    }

    // 数据格式错误异常
    @ExceptionHandler(NumberFormatException.class)
    public String formatHandler(){
        return "/err2.jsp";
    }
}
2. 针对不同的异常展示不同的jsp页面
38-SpringMVC_第56张图片

九、拦截器

①:拦截器介绍

SpringMVC提供的拦截器就类似于Servlet–api中的过滤器,可以对控制器的请求进行拦截实现相关的预处理和后处理。

  • 过滤器
    • 是Servlet规范的一部分,所有的web项目都可以使用
    • 过滤器在web.xml配置(可以使用注解),能够拦截所有web清求
  • 拦截器
    • 是SpringMVC框架的实现,只有在SpringMVC框架中才能使用
    • 拦截器在SpringMVC配置文件进行配置,不会拦截SpringMVC放行的资源(jsp\html\css.…)

②:自定义拦截器

01.创建拦截器

public class MyInterceptor1 implements HandlerInterceptor{
    // 预处理
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("***********预处理***********");
        Enumeration<String> names = request.getParameterNames();
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            if ("bookName".equals(name)){
                return true;
            }
        }
        response.setStatus(400);
        return false;
    }
    
    // 后处理
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("***********后处理***********");
        modelAndView.addObject("tips","这是通过拦截器的后处理添加的数据");
    }
    
}

02. 配置拦截器

    <mvc:interceptors>
        <mvc:interceptor>

            <mvc:mapping path="/book/query"/>
            <mvc:mapping path="/book/add"/>
            

            <mvc:mapping path="/student/**"/>
            <mvc:exclude-mapping path="/student/add"/>
            
            <bean class="com.it.utils.MyInterceptor1"/>
        mvc:interceptor>
    mvc:interceptors>

03.添加控制器方法

在BookConverter类中添加以下方法
    @RequestMapping("query")
    public String query(String bookName){
        System.out.println(bookName);
        Book book = new Book();
        book.setBookName(bookName);
        return "/tips.jsp";
    }
在这里插入图片描述 38-SpringMVC_第57张图片

③:拦截器链

将多个拦截器按照一定的顺序构成一个执行链

38-SpringMVC_第58张图片

十、SSM整合

①:创建Web项目

01. 创建web工程

(完成maven工程web项目结构)步骤略

02. 添加web项目依赖

    <dependency>
      <groupId>javax.servletgroupId>
      <artifactId>jsp-apiartifactId>
      <version>2.0version>
    dependency>
    
    <dependency>
      <groupId>javax.servletgroupId>
      <artifactId>javax.servlet-apiartifactId>
      <version>4.0.1version>
      <scope>providedscope>
    dependency>

03.配置Tomcat运行环境

38-SpringMVC_第59张图片

②:部署MyBatis

01. 添加MyBatis依赖


    <dependency>
      <groupId>mysqlgroupId>
      <artifactId>mysql-connector-javaartifactId>
      <version>8.0.28version>
    dependency>

    <dependency>
      <groupId>org.mybatisgroupId>
      <artifactId>mybatisartifactId>
      <version>3.4.6version>
    dependency>

    <dependency>
      <groupId>org.projectlombokgroupId>
      <artifactId>lombokartifactId>
      <version>1.18.24version>
      <scope>providedscope>
    dependency>

02. 创建mybatis-config.xml


DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

configuration>

③:部署Spring、SpringMVC

01.添加依赖

<dependency>
  <groupId>org.springframeworkgroupId>
  <artifactId>spring-contextartifactId>
  <version>5.3.18version>
dependency>
<dependency>
  <groupId>org.springframeworkgroupId>
  <artifactId>spring-aspectsartifactId>
  <version>5.3.18version>
dependency>
<dependency>
  <groupId>org.springframeworkgroupId>
  <artifactId>spring-jdbcartifactId>
  <version>5.3.18version>
dependency>

<dependency>
  <groupId>org.springframeworkgroupId>
  <artifactId>spring-webartifactId>
  <version>5.3.18version>
dependency>

<dependency>
  <groupId>org.springframeworkgroupId>
  <artifactId>spring-webmvcartifactId>
  <version>5.3.18version>
dependency>

<dependency>
  <groupId>org.springframeworkgroupId>
  <artifactId>spring-testartifactId>
  <version>5.3.18version>
  <scope>testscope>
dependency>
<dependency>
  <groupId>com.fasterxml.jackson.coregroupId>
  <artifactId>jackson-databindartifactId>
  <version>2.13.3version>
dependency>

02.创建Spring配置(多个文件分开配置)

  • spring-context.xml只配置注解声明、以及类的管理

<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"
       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">


    <context:annotation-config/>

    
    <context:component-scan base-package="com.it"/>
beans>
  • spring-mvc.xml进行mvc相关的配置,例如静态资源配置、拦截器配置等

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       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/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    
    <mvc:annotation-driven/>

beans>
  • spring-mybatis.xml进行Spring-与MyBatis整合相关的配置

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">
    
beans>

④:配置SpringMvc前端控制器

  • 在web.xml进行配置
<servlet>
    <servlet-name>springmvcservlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    <init-param>
        <param-name>contextConfigLocationparam-name>
        <param-value>classpath:spring-*.xmlparam-value>
    init-param>
    <load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
    <servlet-name>springmvcservlet-name>
    <url-pattern>/url-pattern>
servlet-mapping>

⑤:整合配置(IOC)

01.导入mybatis-spring依赖

 <dependency>
   <groupId>org.mybatisgroupId>
   <artifactId>mybatis-springartifactId>
   <version>2.0.6version>
 dependency>

02.配置druid连接池

  • 添加druid依赖
 <dependency>
   <groupId>com.alibabagroupId>
   <artifactId>druidartifactId>
   <version>1.2.8version>
 dependency>
  • 创建druid.properties并配置
druid.driver=com.mysql.jdbc.Driver
druid.url=jdbc:mysql://localhost:3306/db_mybatis_demo2?characterEncoding=utf-8
druid.username=root
druid.password=root

## 连接池参数
druid.pool.init=1
druid.pool.minIdle=3
druid.pool.maxActive=20
druid.pool.timeout=30000
  • 在spring-mybatis.xml配置数据源

    <context:property-placeholder location="classpath:druid.properties"/>
    
    <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${druid.driver}"/>
        <property name="url" value="${druid.url}"/>
        <property name="username" value="${druid.username}"/>
        <property name="password" value="${druid.password}"/>
        
        <property name="initialSize" value="${druid.pool.init}"/>
        <property name="minIdle" value="${druid.pool.minIdle}"/>
        <property name="maxActive" value="${druid.pool.maxActive}"/>
        <property name="maxWait" value="${druid.pool.timeout}"/>
     bean>

03.配置SqlSessionFactory

  • 在spring-mybatis.xml进行配置
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="druidDataSource"/>
    <property name="mapperLocations" value="classpath:mappers/*.xml"/>
    <property name="typeAliasesPackage" value="com.it.beans"/>
    <property name="configLocation" value="classpath:mybatis-config.xml"/>
bean>
38-SpringMVC_第60张图片

04.配置MapperScannerConfigurer


    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <property name="basePackage" value="com.it.dao"/>
    bean>
38-SpringMVC_第61张图片

⑥:整合配置(AOP)

使用Spring提供的事务管理完成DAO操作的事务管理

  • 基于注解的事务管理配置:
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="druidDataSource"/>
    bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>

⑦:整合测试

01.完成User的查询操作

  • 创建实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class User {
    private int userId;
    private String userName;
    private String userPwd;
    private String realName;
    private String userImg;
}
38-SpringMVC_第62张图片
  • 在DAO包中创建接口
public interface UserDAO {
    User queryUserByName(String userName);
}
38-SpringMVC_第63张图片
  • 在Mappers文件下创建映射文件

DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.it.dao.UserDAO">

    <resultMap id="UserMap" type="User">
        <id column="user_id" property="userId"/>
        <result column="user_name" property="userName"/>
        <result column="user_pwd" property="userPwd"/>
        <result column="user_realname" property="realName"/>
        <result column="user_img" property="userImg"/>
    resultMap>

    <select id="queryUserByName" resultMap="UserMap">
        select user_id,user_name,user_pwd,user_realname,user_img
        from users
        where user_name= #{userName}
    select>

mapper>

02. 对DAO单元测试

  • 添加junit、spring-test(前面已经导入过)依赖
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
  • 创建测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring-context.xml",
                       "classpath:spring-mvc.xml",
                       "classpath:spring-mybatis.xml"})
public class UserDAOTest {

    @Autowired
    private UserDAO userDAO;

    @Test
    public void queryUserByName() {
        User user = userDAO.queryUserByName("李四");
        System.out.println(user);
    }
}
38-SpringMVC_第64张图片

03.对Service单元测试

1. 创建接口方法
public interface UserService {
    User checkLogin(String username, String password);
}
38-SpringMVC_第65张图片
2. 创建接口实现类
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDAO userDAO;

    @Override
    @Transactional
    public User checkLogin(String username, String password) {
        User user = userDAO.queryUserByName("李四");
        if (user != null & user.getUserPwd().equals(password)){
            return user;
        }
        return null;
    }
}
38-SpringMVC_第66张图片
3. 测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring-context.xml",
        "classpath:spring-mvc.xml",
        "classpath:spring-mybatis.xml"})
public class UserServiceTest {

    @Resource
    private UserService userService;

    @Test
    public void checkLogin() {
        User user = userService.checkLogin("李四", "123123");
        System.out.println(user);
    }
}
38-SpringMVC_第67张图片

⑧:整合Controller

1. 创建UserController
@Controller
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService;

    @RequestMapping("/login")
    public String login(String username, String password, HttpServletRequest request){
        User user = userService.checkLogin(username, password);
        if (user == null){
            request.setAttribute("tips","用户名或密码错误!");
            return "/login.jsp";
        }else {
            request.getSession().setAttribute("user",user);
            return "/index.jsp";

        }
    }
}
38-SpringMVC_第68张图片
2. 创建index.jsp页面
<%@page contentType="text/html;charset=utf-8" language="java" pageEncoding="UTF-8" %>

<html>
<head>

    <title>Titletitle>
head>
<body>
<h3>这是主页面~h3>
<h4>Hello ${user.userName}~~h4>
body>
html>
3. 创建login.jsp页面
<%@page contentType="text/html;charset=utf-8" language="java" pageEncoding="UTF-8" %>

<html>
<head>
    <base href="${pageContext.request.contextPath}/">
    <title>Titletitle>
head>
<body>
<h3>登录页面h3>
${tips}
<form action="user/login" method="post">
    <p>账号:<input type="text" name="username">p>
    <p>密码:<input type="password" name="password">p>
    <p><input type="submit" value="登录">p>
form>
body>
html>
4. 测试
38-SpringMVC_第69张图片

十一 纯注解开发(补)

①:使用注解开发(入门案例)

38-SpringMVC_第70张图片

1. 导入依赖

    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-webmvcartifactId>
      <version>5.3.18version>
    dependency>
    <dependency>
      <groupId>javax.servletgroupId>
      <artifactId>javax.servlet-apiartifactId>
      <version>4.0.1version>
      <scope>providedscope>
    dependency>
2. 创建控制器类
// 2.1 使用Controller定义bean
@Controller
// 2.2 设置当前操作的访问路径
@RequestMapping("user")
public class UserController {

    @RequestMapping("add")
    // 2.3 设置返回类型
    @ResponseBody
    public String addUser(String username){
        System.out.println("*******User  add*******"+username);
        return "{'module':'username'}";
    }
}
38-SpringMVC_第71张图片
3. 创建springmvc的配置类,加载controller对应的bean
// 3. 创建springmvc的配置类,加载controller对应的bean
@Configuration
@ComponentScan("com.it.controller")
public class SpringMvcConfig {
}
38-SpringMVC_第72张图片
4. 4. 定义一个serlvet容器启动的配置类,在里面加载spring的配置
// 4. 定义一个serlvet容器启动的配置类,在里面加载spring的配置
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {

    // 该方法:加载springMvc容器配置
    @Override
    protected WebApplicationContext createServletApplicationContext() {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(SpringMvcConfig.class);
        return context;
    }
    // 该方法:设置哪些请求归属springmvc处理
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
    // 该方法:加载spring容器的配置
    @Override
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }
}
在这里插入图片描述
5. 测试
38-SpringMVC_第73张图片

②:bean加载控制

38-SpringMVC_第74张图片

1. 设定扫描范围为精确范围
38-SpringMVC_第75张图片
2. 排除掉controller包内的bean
38-SpringMVC_第76张图片
3. 不区分Spring与SpringMVC的环境,加载到同一个环境中
// 4. 定义一个serlvet容器启动的配置类,在里面加载spring的配置
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {

    // 该方法:加载springMvc容器配置
    @Override
    protected WebApplicationContext createServletApplicationContext() {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(SpringMvcConfig.class);
        return context;
    }

    // 该方法:加载spring容器的配置
    @Override
    protected WebApplicationContext createRootApplicationContext() {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(SpringConfig.class);
        return context;
    }

    // 该方法:设置哪些请求归属springmvc处理
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}
38-SpringMVC_第77张图片
4. 不区分Spring与SpringMVC的环境,加载到同一个环境中(简化版)
// 4. 定义一个serlvet容器启动的配置类,在里面加载spring的配置
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMvcConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}
38-SpringMVC_第78张图片

③:PostMan工具

官网:[https://www.postman.com/](https://www.postman.com/)
38-SpringMVC_第79张图片

④:postman发送get和post请求

38-SpringMVC_第80张图片

1. get请求
38-SpringMVC_第81张图片 38-SpringMVC_第82张图片
2. post请求
38-SpringMVC_第83张图片38-SpringMVC_第84张图片
3. 解决post请求中文乱码
    // 乱码处理

    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("utf-8");
        return new Filter[] {filter};
    }
38-SpringMVC_第85张图片 38-SpringMVC_第86张图片

⑤post发送json数据

在这里插入图片描述

1. 导入jackson-databind依赖
    <dependency>
      <groupId>com.fasterxml.jackson.coregroupId>
      <artifactId>jackson-databindartifactId>
      <version>2.13.3version>
    dependency>
2. 在springmvc配置文件中添加@EnableWebMvc
在这里插入图片描述

01. 集合参数(Json)

    // 集合参数(json)
    @RequestMapping("list")
    @ResponseBody
    public String listParamForJson(@RequestBody List<String> lists){
        System.out.println("lists = " + lists);
        return lists.toString();
    }
38-SpringMVC_第87张图片38-SpringMVC_第88张图片

02. pojo参数(Json)

    // pojo参数(json)
    @RequestMapping("users")
    @ResponseBody
    public String pojoParamForJson(@RequestBody User users){
        System.out.println("users = " + users);
        return "users = " + users;
    }
38-SpringMVC_第89张图片38-SpringMVC_第90张图片

03. pojo集合参数

    // pojo集合参数(json)
    @RequestMapping("listUser")
    @ResponseBody
    public String listPojoParamForJson(@RequestBody List<User> users){
        System.out.println("users = " + users);
        return "users = " + users;
    }
38-SpringMVC_第91张图片38-SpringMVC_第92张图片

04. 日期参数

    // 日期参数
    @RequestMapping("date")
    @ResponseBody
    public String dateParam(Date date,
                            @DateTimeFormat(pattern = "yyyy-MM-dd") Date date2,
                            @DateTimeFormat(pattern = "yyyy/MM/dd HH:mm:ss") Date date3){
        System.out.println("date = " + date);
        System.out.println("date2 = " + date2);
        System.out.println("date3 = " + date3);
        return date+","+date2+","+date3;
    }
38-SpringMVC_第93张图片38-SpringMVC_第94张图片

⑤:REST风格

38-SpringMVC_第95张图片

01. 入门案例

38-SpringMVC_第96张图片38-SpringMVC_第97张图片38-SpringMVC_第98张图片

1. 在BookController类中添加增删改查方法
@Controller
public class BookController {

    @RequestMapping(value = "books", method = RequestMethod.POST)
    @ResponseBody
    public String add(){
        System.out.println("Book  add *****");
        return "Book  add *****";
    }

    @RequestMapping(value ="books/{id}",method = RequestMethod.DELETE)
    @ResponseBody
    public String delete(@PathVariable Integer id){
        System.out.println("Book  delete *****" + id);
        return "Book  delete *****" + id;
    }

    @RequestMapping(value ="books", method = RequestMethod.PUT)
    @ResponseBody
    public String update(@RequestBody Book book){
        System.out.println("Book  update *****" + book);
        return "Book  update *****" + book;
    }

    @RequestMapping(value ="books/{id}", method = RequestMethod.GET)
    @ResponseBody
    public String getById(@PathVariable Integer id){
        System.out.println("Book  getById *****" + id);
        return "Book  getById *****" + id;
    }
}
38-SpringMVC_第99张图片38-SpringMVC_第100张图片38-SpringMVC_第101张图片

38-SpringMVC_第102张图片

02.RESTful快速开发

38-SpringMVC_第103张图片38-SpringMVC_第104张图片

@RestController
@RequestMapping("books")
public class BookController2 {

    @PostMapping
    public String add(){
        System.out.println("Book  add *****");
        return "Book  add *****";
    }

    @DeleteMapping("{id}")
    public String delete(@PathVariable Integer id){
        System.out.println("Book  delete *****" + id);
        return "Book  delete *****" + id;
    }

    @PutMapping
    public String update(@RequestBody Book book){
        System.out.println("Book  update *****" + book);
        return "Book  update *****" + book;
    }

    @GetMapping("{id}")
    public String getById(@PathVariable Integer id){
        System.out.println("Book  getById *****" + id);
        return "Book  getById *****" + id;
    }
}

⑥:基于RESTful页面数据交互

01.数据准备

1. 创建实体类
38-SpringMVC_第105张图片
2. 创建config配置文件
38-SpringMVC_第106张图片
@Controller
@ComponentScan("com.it.controller")
@EnableWebMvc
public class SpringMvcConfig {
}

public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[0];
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMvcConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    // 乱码处理
    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("utf-8");
        return new Filter[]{filter};
    }
}

2. 创建Controller类
@RestController
@RequestMapping("/books")
public class BookController {

    @PostMapping
    public String save(@RequestBody Book book){
        System.out.println("*******Book  save*******" + book);
        return "*******Book  save*******" + book;
    }

    @GetMapping
    public List<Book> getAll(){
        ArrayList<Book> bookList = new ArrayList<>();

        Book book1 = new Book();
        book1.setType("计算机");
        book1.setName("Java核心");
        book1.setDescription("从入门到精通~");
        bookList.add(book1);

        Book book2 = new Book();
        book2.setType("计算机");
        book2.setName("Linux核心");
        book2.setDescription("从入门到精通~");
        bookList.add(book2);

        return bookList;
    }


}

3. 测试
38-SpringMVC_第107张图片在这里插入图片描述

02. 放行静态资源

38-SpringMVC_第108张图片

1
38-SpringMVC_第109张图片
2. 创建SpringMvcSupport类
38-SpringMVC_第110张图片
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/pages/**","/pages/");
        registry.addResourceHandler("/js/**","/js/");
        registry.addResourceHandler("/css/**","/css/");
        registry.addResourceHandler("/plugins/**","/plugins/");
    }
}

十二、纯注解SSM整合(补)

①:整合配置

38-SpringMVC_第111张图片

1. 导入依赖
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-webmvcartifactId>
      <version>5.3.18version>
    dependency>
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-jdbcartifactId>
      <version>5.3.18version>
    dependency>
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-testartifactId>
      <version>5.3.18version>
    dependency>
    <dependency>
      <groupId>org.mybatisgroupId>
      <artifactId>mybatisartifactId>
      <version>3.4.6version>
    dependency>
    <dependency>
      <groupId>junitgroupId>
      <artifactId>junitartifactId>
      <version>4.13version>
      <scope>testscope>
    dependency>
    <dependency>
      <groupId>javax.servletgroupId>
      <artifactId>servlet-apiartifactId>
      <version>2.5version>
    dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.coregroupId>
      <artifactId>jackson-databindartifactId>
      <version>2.13.3version>
    dependency>
    <dependency>
      <groupId>org.projectlombokgroupId>
      <artifactId>lombokartifactId>
      <version>1.18.24version>
    dependency>
    <dependency>
      <groupId>mysqlgroupId>
      <artifactId>mysql-connector-javaartifactId>
      <version>8.0.28version>
    dependency>
    <dependency>
      <groupId>com.alibabagroupId>
      <artifactId>druidartifactId>
      <version>1.2.8version>
    dependency>
    <dependency>
      <groupId>org.mybatisgroupId>
      <artifactId>mybatis-springartifactId>
      <version>2.0.6version>
    dependency>
2. 创建配置文件
38-SpringMVC_第112张图片
@Configuration
@ComponentScan("com.it.service")
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class, MyBatisConfig.class})
public class SpringConfig {
}
public class JdbcConfig {

    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    @Bean
    public DataSource datasource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }
}
public class MyBatisConfig {

    @Bean
    public SqlSessionFactoryBean sessionFactory(DataSource dataSource){
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        factoryBean.setTypeAliasesPackage("com.it.domain");
        return factoryBean;
    }

    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer configurer = new MapperScannerConfigurer();
        configurer.setBasePackage("com.it.dao");
        return configurer;
    }
}
@Configuration
@ComponentScan("com.it.controller")
@EnableWebMvc
public class SpringMvcConfig {
}
public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMvcConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_mybatis_demo2?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

②:功能模块开发

1. 创建数据表
create table books(
    id int auto_increment primary key ,
    type varchar(20) not null ,
    name varchar(50) not null ,
    description varchar(255)
)
insert into books (type, name, description)
VALUES ('计算机理论', 'Spring?实战第5版', 'Spring入门经典教程,深入理解Spring.原理技术内幕'),
       ('计算机理论', 'Spring5核心原理与30个类手写实战', '十年沉淀之作,手写Spring精华思想'),
       ('计算机理论', 'Spring5设计模式', '深入Spring源码剖析Spring源码中蕴含的10大设计模式'),
       ('计算机理论', 'Spring MVC+MyBatis开发从入门到项目实战', '全方位解析面向Web应用的轻量级框架,带你成为Spring MVC开发高手'),
       ('计算机理论', '轻量级Java Web企业应用实战', '源码级剖析Spring框架,适合已掌握)ava基础的读者'),
       ('计算机理论', 'Java核心技术卷1基础知识(原书第11版)', 'Core Java第11版,Jolt大奖获奖作品,针对ava SE9、10、11全面更新'),
       ('计算机理论', '深入理解Java虚拟机', '5个维度全面剖析VM,大厂面试知识点全覆盖'),
       ('计算机理论', 'Java编程思想(第4版)', 'Java学习必读经典,殿堂级著作!赢得了全球程序员的广泛赞誉'),
       ('计算机理论', '零基础学ava(全彩版)', '零基础自学编程的入门图书,由浅入深,详解)va语言的编程思想和核心技术'),
       ('市场营销', '直播就该这么做:主播高效沟通实战指南', '李子柒、李佳琦、薇娅成长为网红的秘密都在书中'),
       ('市场营销', '直播销讲实战一本通', '和秋叶一起学系列网络营销书籍'),
       ('市场营销', '直播带货:淘宝、天猫直播从新手到高手', '一本教你如何玩转直播的书,10堂课轻松实现带货月入3W+');
2. 创建实体类
38-SpringMVC_第113张图片
3. 定义BookDao接口方法
public interface BookDao {

    @Insert("insert into books (type, name, description) values (#{type}, #{name}, #{description})")
    public int save(Book book);

    @Update("update books set type = #{type}, name = #{name}, description = #{description} where id = #{id}")
    public int update(Book book);

    @Delete("delete from books where id = #{id}")
    public int delete(Integer id);

    @Select("select * from books where id = #{id}")
    public Book getById(Integer id);

    @Select("select * from books")
    public List<Book> getAll();
}
4. 定义BookService接口方法
public interface BookService {

    public boolean addBook(Book book);

    public boolean updateBook(Book book);

    public boolean deleteBook(Integer id);

    public Book getBookById(Integer id);

    public List<Book> getAllBooks();
}
5. 创建BookService实现类BookServiceImpl
@Service
public class BookServiceImpl implements BookService {

    @Autowired
    private BookDao bookDao;

    @Override
    public boolean addBook(Book book) {
        return bookDao.save(book) > 0;
    }

    @Override
    public boolean updateBook(Book book) {
        return bookDao.update(book) > 0;
    }

    @Override
    public boolean deleteBook(Integer id) {
        return bookDao.delete(id) > 0;
    }

    @Override
    public Book getBookById(Integer id) {
        return bookDao.getById(id);
    }

    @Override
    public List<Book> getAllBooks() {
        return bookDao.getAll();
    }
}
5.2 IDEA检查自动装配报错
38-SpringMVC_第114张图片38-SpringMVC_第115张图片
6. 创建BookController与页面交互
@RestController
@RequestMapping("/books")
public class BookController {

    @Autowired
    private BookService bookService;

    @PostMapping
    public boolean addBook(@RequestBody Book book) {
        return bookService.addBook(book);
    }
    @PutMapping
    public boolean updateBook(@RequestBody Book book) {
        return bookService.updateBook(book);
    }

    @DeleteMapping("{id}")
    public boolean deleteBook(@PathVariable Integer id) {
        return bookService.deleteBook(id);
    }
    @GetMapping("/{id}")
    public Book getBookById(@PathVariable Integer id) {
        return bookService.getBookById(id);
    }
    @GetMapping
    public List<Book> getAllBooks() {
        return bookService.getAllBooks();
    }
}

③:接口测试

1. 业务层接口测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class BookServiceTest {

    @Autowired
    private BookService bookService;

    @Test
    public void addBook() {
        Book book = new Book(0,"计算机类","Java核心卷Ⅱ","从入门到精通");
        boolean b = bookService.addBook(book);
        System.out.println(b);
    }

    @Test
    public void updateBook() {
        Book book = new Book(13,"计算机类","Java核心卷Ⅲ","从入门到秃顶");
        bookService.updateBook(book);
    }

    @Test
    public void deleteBook() {
        boolean b = bookService.deleteBook(13);
        System.out.println(b);
    }

    @Test
    public void getBookById() {
        Book book = bookService.getBookById(1);
        System.out.println(book);
    }

    @Test
    public void getAllBooks() {
        List<Book> allBooks = bookService.getAllBooks();
        for (int i = 0; i < allBooks.size(); i++) {
            System.out.println(allBooks.get(i));
        }
    }
}
2. 表现层接口测试
38-SpringMVC_第116张图片38-SpringMVC_第117张图片

38-SpringMVC_第118张图片
38-SpringMVC_第119张图片38-SpringMVC_第120张图片

④:事务管理

1. 开启注解事务驱动
38-SpringMVC_第121张图片
2. 创建事务管理器
    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource){
        DataSourceTransactionManager manager = new DataSourceTransactionManager();
        manager.setDataSource(dataSource);
        return manager;
    }
38-SpringMVC_第122张图片
3.
在这里插入图片描述

⑤:乱码处理

    // 乱码处理

    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("utf-8");
        return new Filter[]{filter};
    }
38-SpringMVC_第123张图片

⑥:表现层与前端数据协议实现

1. 在controller包下创建Result用于封装数据
38-SpringMVC_第124张图片
2. 在controller包下创建Code类定义所有的状态码值
public class Code {
    // 定义成功的状态码
    public static final Integer SAVE_OK = 20011;
    public static final Integer DELETE_OK = 20021;
    public static final Integer UPDATE_OK = 20031;
    public static final Integer GET_OK = 20041;

    // 定义失败的状态码
    public static final Integer SAVE_ERR = 20010;
    public static final Integer DELETE_ERR = 20020;
    public static final Integer UPDATE_ERR = 20030;
    public static final Integer GET_ERR = 20040;
}
3. 修改BookController中的代码
@RestController
@RequestMapping("/books")
@Transactional
public class BookController {

    @Autowired
    private BookService bookService;

    @PostMapping
    public Result addBook(@RequestBody Book book) {
        boolean flag = bookService.addBook(book);
        return new Result(flag ? Code.SAVE_OK:Code.SAVE_ERR,flag);
    }
    @PutMapping
    public Result updateBook(@RequestBody Book book) {
        boolean flag = bookService.updateBook(book);
        return new Result(flag ? Code.UPDATE_OK:Code.UPDATE_ERR,flag);
    }

    @DeleteMapping("{id}")
    public Result deleteBook(@PathVariable Integer id) {
        boolean flag = bookService.deleteBook(id);
        return new Result(flag ? Code.DELETE_OK:Code.DELETE_ERR,flag);
    }
    @GetMapping("/{id}")
    public Result getBookById(@PathVariable Integer id) {
        Book book = bookService.getBookById(id);
        Integer code = book != null ? Code.GET_OK : Code.GET_ERR;
        String msg = book != null ? "" : "数据查询失败,请重试!";
        return new Result(code, book,msg);
    }
    @GetMapping
    public Result getAllBooks() {
        List<Book> bookList = bookService.getAllBooks();
        Integer code = bookList != null ? Code.GET_OK : Code.GET_ERR;
        String msg = bookList != null ? "" : "数据查询失败,请重试!";
        return new Result(code, bookList,msg);
    }
}
4. 测试
38-SpringMVC_第125张图片38-SpringMVC_第126张图片38-SpringMVC_第127张图片

⑦:异常处理

01. 异常处理器

38-SpringMVC_第128张图片38-SpringMVC_第129张图片

1. 在controller包下创建ProjectExceptionAdvice类
@RestControllerAdvice
public class ProjectExceptionAdvice {
    @ExceptionHandler(Exception.class) // 指定处理哪种类型的异常
    public Result doException(){
        return new Result(666,null,"出异常啦");
    }
}
2. 测试(在根据id查询Book方法中制造一个异常)
38-SpringMVC_第130张图片

02. 异常处理方案

38-SpringMVC_第131张图片

1. 创建exception包并在包内创建SystemException(系统异常)类和SystemException(业务异常)类
38-SpringMVC_第132张图片
public class BusinessException extends RuntimeException{
    private Integer code;
    
    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }
    public BusinessException(Integer code, String message) {
        super(message);
        this.code = code;
    }

    public BusinessException(Integer code, String message, Throwable cause) {
        super(message, cause);
        this.code = code;
    }
}
2. 定义异常状态码Code(在Code类添加以下代码)
    // 定义异常状态码
    public static final Integer SYSTEM_ERR = 50001;
    public static final Integer SYSTEM_TIMEOUT_ERR = 50002;
    public static final Integer SYSTEM_UNKNOW_ERR = 59999;
    public static final Integer BUSINESS_ERR = 60002;
3. 模拟异常代码
38-SpringMVC_第133张图片
    @Override
    public Book getBookById(Integer id) {
        // 将可能出现的异常进行包装,转换成自定义异常
        // 方法1
        if(id == 1){
            throw new BusinessException(Code.BUSINESS_ERR,"请不要使用你的技术挑战我的耐心");
        }

        // 方法2
        try {
            int i = 1 /0;
        }catch (Exception e) {
            throw new SystemException(Code.SYSTEM_TIMEOUT_ERR,"服务器访问超时,请重试");
        }

        return bookDao.getById(id);
    }
3. 修改异常处理器(ProjectExceptionAdvice)中的代码
@RestControllerAdvice
public class ProjectExceptionAdvice {
    @ExceptionHandler(SystemException.class) // 指定处理哪种类型的异常
    public Result doSystemException(SystemException e){
        // 记录日志
        // 发消息给运维
        // 发送邮件给开发人员
        return new Result(e.getCode(),null,e.getMessage());
    }

    @ExceptionHandler(BusinessException.class) // 指定处理哪种类型的异常
    public Result doBusinessException(BusinessException e){
        return new Result(e.getCode(),null,e.getMessage());
    }


    @ExceptionHandler(Exception.class) // 指定处理哪种类型的异常
    public Result doException(){
        // 记录日志
        // 发消息给运维
        // 发送邮件给开发人员
        return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙,请稍后再试");
    }
}
4. 测试

38-SpringMVC_第134张图片
38-SpringMVC_第135张图片

⑧:放行静态资源

1. 在config包下创建SpringMvcSupport类
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
        registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
    }
}
2. 将SpringMvcSypport类加入到SpringMvcConfig中
38-SpringMVC_第136张图片

十三、拦截器

38-SpringMVC_第137张图片

①:拦截器入门

1. 创建ProjectInterceptor类(定义拦截器)
@Controller
public class ProjectInterceptor implements HandlerInterceptor{
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle~~~~");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle~~~~");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion~~~~");
    }
}
38-SpringMVC_第138张图片 38-SpringMVC_第139张图片

|

2. 配置执行哪些请求时进行拦截(在SpringMvcSupport)添加一部分代码
38-SpringMVC_第140张图片
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {

    @Autowired  // 使用自动装配完成拦截器的注入
    private ProjectInterceptor projectInterceptor;

    // 释放静态资源
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
        registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
    }

    // 配置拦截对象
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        // 只要请求books这个请求路径是就进行拦截
        registry.addInterceptor(projectInterceptor).addPathPatterns("/books", "/books/*");
    }
}

②:简化以上开发

1. 直接在SpringMvcConfig类中实现WebMvcConfigurer接口(但有侵入的缺陷)
38-SpringMVC_第141张图片
@Configuration
@ComponentScan({"com.it.controller","com.it.config"})
@EnableWebMvc
public class SpringMvcConfig implements WebMvcConfigurer{

    @Autowired  // 使用自动装配完成拦截器的注入
    private ProjectInterceptor projectInterceptor;

    // 释放静态资源
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
        registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
    }

    // 配置拦截对象
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 只要请求books这个请求路径是就进行拦截
        registry.addInterceptor(projectInterceptor).addPathPatterns("/books", "/books/*");
    }
}

③:拦截器参数

38-SpringMVC_第142张图片## ④:拦截器链配置

1. 在创建一个拦截器
38-SpringMVC_第143张图片
@Controller
public class ProjectInterceptor2 implements HandlerInterceptor{
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle~~~~222");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle~~~~222");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion~~~~222");
    }
}

2. 将拦截器2加入到SpringMvcConfig中
38-SpringMVC_第144张图片
@Configuration
@ComponentScan({"com.it.controller","com.it.config"})
@EnableWebMvc
public class SpringMvcConfig implements WebMvcConfigurer{

    @Autowired  // 使用自动装配完成拦截器的注入
    private ProjectInterceptor projectInterceptor;
    @Autowired
    private ProjectInterceptor2 projectInterceptor2;

    // 释放静态资源
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
        registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
    }

    // 配置拦截对象
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 只要请求books这个请求路径是就进行拦截
        registry.addInterceptor(projectInterceptor).addPathPatterns("/books", "/books/*");
        registry.addInterceptor(projectInterceptor2).addPathPatterns("/books", "/books/*");
    }
}

38-SpringMVC_第145张图片

你可能感兴趣的:(java-Spring,Java,spring,mvc,java)