6. SpringMVC整理

98 阅读10分钟

一、初识SpringMVC

ssmmybatis + Spring + SpringMVC

1.1 什么是MVC

MVC:是一种软件设计规范,是将业务逻辑、数据、显示分离的方法来组织代码。主要作用是降低了视图与业务逻辑的双向解耦。

  • 模型Model(dao、Service):数据模型,提供要展示的数据,包含数据和行为
  • 视图View(JSP):负责模型的展示
  • 控制器Controller(Servlet):接收用户请求,委托给Model处理,处理完后返回给View

1.2 回顾Servlet

创建一个Maven项目作为父工程,并创建Maven子项目

  • 导入依赖
<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.3</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
</dependencies>
  • 添加框架支持

目前项目是一个Maven项目,需要将其变为web项目,在项目名上右键,选择Add Framework Support,勾选Web Application

  • 子项目导入依赖
<dependencies>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.2</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
  • 创建类并继承HttpServlet然后重写doGetdoPost
  • 编写doGet
@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1.获取前端参数
        String method = req.getParameter("method");
        if (method.equals("add")) {
            req.getSession().setAttribute("msg", "执行add方法");
        }

        if (method.equals("delete")) {
            req.getSession().setAttribute("msg", "执行delete方法");
        }

        // 2.视图转发req或重定向resp
        req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req, resp);
    }
  • 编写jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>

<body>

${msg}

</body>
</html>
  • web.xml中注册servlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.nick.servlet.HelloServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

</web-app>
  • 写一个页面来调用Servlet
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>表单</title>
</head>

<body>

<form action="/hello" method="post">
    <input type="text" name="method">
    <input type="submit">
</form>

</body>
</html>
  • 配置Tomcat

image.png

  • 访问

image.png

1.3 学习SpringMVC

SpringMVC是Spring Framework的一部分,是基于Java实现的MVC轻量级Web框架。

  • 轻量级,简单易学
  • 高效,基于请求响应的MVC框架
  • 与Spring无缝结合
  • 约定大于配置
  • 功能强大:RESTful、数据验证、格式化、本地化
  • 中心控制器

Spring的Web框架围绕**DispatcherServlet**设计,DispatcherServlet作用是将请求分发到不同的处理器

image.png

SpringMVC原理图:

image.png

搭建SpringMVC项目

  • 新建一个Module,添加Web支持
  • 配置web.xml,注册DispatcherServlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--1. 注册DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--关联一个springmvc的配置文件-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <!--启动级别1-->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!--/匹配所有的请求(不包括.jsp)-->
    <!--/*匹配所有的请求(包括.jsp)-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>
  • 创建DispatcherServlet的配置文件springmvc-servlet.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"
       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">

    <!--5. 添加处理映射器-->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    <!--6. 添加处理适配器-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
    <!--7. 添加视图解析器
    1. 获取ModelAndView的数据
    2. 解析ModelAndView视图名字
    3. 拼接视图名字,找到对应的视图
    4. 将数据渲染到视图上
    -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>

    <bean id="/hello" class="com.nick.controller.HelloController"/>

</beans>
  • 编写Controller
public class HelloController implements Controller {
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        // ModelAndView模型和视图
        ModelAndView mv = new ModelAndView();

        // 封装对象,放在ModelAndView中
        mv.addObject("msg", "HelloSpringMVC");
        // 封装要跳转的视图,放到ModelAndView中
        mv.setViewName("hello"); // /WEB-INF/hello.jsp
        return mv;
    }
}
  • 编写hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

${msg}

</body>
</html>
  • springmvc-servlet.xml中配置controller的bean

  • 测试

image.png

1.4 SpringMVC执行原理(重要)

image.png

  • (1)前端页面访问,会先走到DispatcherServlet

  • (2,3,4)DispatcherServlet会去找处理器映射HandlerMapping,它会根据URL查找处理器/hello,并返回给DispatcherServlet

  • (5,6,7,8)DispatcherServlet根据/hello去找处理器适配器,找到具体的HelloController,该Controller会处理相关业务,并返回一个ModelAndView,里面包含传递的消息和要跳转的视图

  • (9,10)DispatcherServlet拿着ModelAndView去找视图解析器ViewResolver,视图解析器会解析视图名称,找对应的视图XXX.jsp,然后将数据渲染到视图上

  • (11)DispatcherServlet根据视图解析器解析视图的结果,调用具体的视图,最终呈现给用户

image.png

1.5 使用注解开发SpringMVC

  1. 新建一个Module,添加web支持
  2. 在pom中引入相关依赖
  3. 配置web.xml
  4. 添加SpringMVC配置文件

这里不需要配置处理器映射和处理器适配器了,为了支持基于注解的IOC,需要设置自动扫描包的功能。

  • 自动扫描包:context:component-scan
  • 不处理静态资源:mvc:default-servlet-handler
  • HandlerMappingHandlerAdapter注入:mvc:annotation-driven
<!--指定要扫描的包,该包下的注解就会生效-->
<context:component-scan base-package="com.nick.controller"/>

<!--让SpringMVC不处理静态资源 .css .js .html .mp3 .mp4-->
<mvc:default-servlet-handler/>

<!--
    支持mvc注解驱动
        在Spring中一般采用@RequestMapping注解来完成映射关系
        要使@RequestMapping注解生效
        必须向上下文中注册DefaultAnnotationHandlerMapping
        和一个AnnotationMethodHandlerAdapter实例
        这两个实例分别在类级别和方法级别处理
        而annotation-driven配置帮助我们自动完成上述两个实例的注入
    -->
<mvc:annotation-driven/>

<!--    视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <property name="suffix" value=".jsp"/>
</bean>
  1. 创建Controller
@Controller
public class HelloController {
    // 真实访问地址:项目名//hello
    @RequestMapping("/hello")
    public String Hello(Model model) {
        // 封装数据
        model.addAttribute("msg", "HelloSpringMVCAnnotation");

        // 返回视图的名字,返回结果会被视图解析器处理
        return "hello";
    }
}

1.6 Controller配置总结

Controller

  • 控制器复杂提供访问应用程序的行为,通常通过接口定义或者注解定义两种方式
  • 控制器负责解析用户的请求并将其转换为一个模型
  • 在SpringMVC中一个控制器类可以包含多个方法
  • 在SpringMVC中对于Controller的配置方式有很多种

接口方式

  • 编写Controller类

  • 去Spring配置文件中注册请求的Bean,name对应请求路径,class对应处理请求的类

  • 编写web前端

  • 在配置文件中,不用配置映射器和适配器(学习原理使用)

  • 返回ModelAndView类中通过setName来设置视图名称

  • 缺点:一个控制器只能写一个方法,麻烦

注解方式

  • @Controller注解类用于声明Spring类的实例是一个控制器
  • Spring可以使用扫描机制找到应用中所有基于注解的控制器类,为了保证Spring能找到你的控制器,需要在配置文件中声明组件扫描<context:component-scan>
  • 编写Controller类
  • 返回String为视图名称
注解说明
@Component组件(这几个是等价的)
@ServiceService
@ControllerController
@RespositoryDao

1.7 RequestMapping

@RequestMapping注解用于映射url到控制器类或者一个特定的处理程序方法

  • 写在类上时,是父路径
  • 也可以写在方法上,是子路径

二、RESTFul风格

2.1 概念

RestFul风格就是一个资源定位及资源操作的风格,不是标准也不是协议,只是一种风格。基于这种风格设计的软件,更有层次,更易于实现缓存机制。

功能

  • 资源:互联网所有事物都可以被抽象为资源
  • 资源操作:使用POSTDELETEPUTGET不同方法对资源分别进行添加、删除、修改、查询

传统方式操作资源

传统方式通过不同参数来实现不同效果,方法单一,postget

  • 查询(GET):http://127.0.0.1:8080/item/a.action?id=1
  • 新增(POST):http://127.0.0.1:8080/item/b.action
  • 更新(POST):http://127.0.0.1:8080/item/c.action
  • 删除(GET或POST):http://127.0.0.1:8080/item/d.action?id=1

使用RESTFul风格操作资源

RESTFul风格可以通过相同的请求来实现不同的效果,示例就是jira的api使用同一个api,因为方法的不同产生不同的作用

  • 查询(GET):http://127.0.0.1:8080/item/1
  • 新增(POST):http://127.0.0.1:8080/item
  • 更新(POST):http://127.0.0.1:8080/item
  • 删除(GET或POST):http://127.0.0.1:8080/item

2.2 示例

示例

  • 传统风格
@Controller
public class TestController {
    @RequestMapping("/add")
    String testController(int a, int b, Model model) {
        int res = a + b;
        model.addAttribute("msg", "res=" + res);
        return "test";
    }
}

image.png

  • RESTFul风格

在SpringMVC中可以使用**@PathVariable**注解,让方法参数的值对应绑定到一个URI模板变量上

@RequestMapping("/add2/{a}/{b}")
String testController2(@PathVariable int a, @PathVariable int b, Model model) {
    int res = a + b;
    model.addAttribute("msg", "res=" + res);
    return "test";
}

image.png

优点:这种RESTFul风格不会将参数名暴露给用户,更安全

三、重定向与转发

  • 方式一:使用ServletAPI

重定向

  • 方法:sendRedirect
  • 类:HttpServletResponse

转发:

  • 方法:getRequestDispatcher
  • 类:HttpServletResponse
  • 方式二:使用SpringMVC方式,修改Controller的返回值

有视图解析器的时候,直接返回"xxx",视图解析器会拼接前缀和后缀,默认是转发。

使用重定向或者转发的方式,直接返回路径加后缀,因此不需要视图解析器了。

重定向

  • return "redirect:/xxx.jsp"

转发

  • return "forward:/xxx.jsp"
  • return "/xxx.jsp"

四、接收请求参数及数据回显

4.1 接收请求参数

  1. 提交的与名称和处理方法参数名一致,可以直接处理

image.png

  1. 提交的域名称和处理方法的参数名不一致

image.png

  1. 提交一个对象
  • 会自动匹配对象中的字段名,如果一致则可以直接使用对象来接收

image.png

4.2 数据回显

  1. 通过ModelAndView

image.png

  1. 通过ModelMap

image.png

  1. 通过Model

image.png

区别

  • Model:精简版,大部分情况下直接使用Model
  • ModelMap:继承LinkedHashMap,所以有其所有功能
  • ModelAndView:可以在存储数据的同时,进行设置返回逻辑视图

4.3 解决乱码问题

使用过滤器来解决乱码

使用自定义过滤器

  1. 实现Filter接口

image.png

  1. 进行配置

image.png

使用SpringMVC过滤器

org.springframework.web.filter.CharacterEncodingFilter

CharacterEncodingFilter类本质还是实现filter,但是其做了很多其他工作

五、JSON讲解

5.1 什么是JSON

  • JSON(JavaScript Object Notation,JS对象标记)是一种轻量级的数据交换格式,目前使用特别广泛
  • 采用完全独立的编程语言文本格式来存储和表示数据
  • 简洁清晰的层次结构

在JavaScript中,一切皆对象,因此JavaScript支持的类型都可以通过JSON来表示,例如字符串、数字、对象、数组等

  • 对象表示为键值对,数据由逗号分隔
  • 花括号保存对象
  • 方括号保存数组

image.png

5.2 Jackson使用

5.2.1 基础使用

  • 导包
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.1</version>
</dependency>
  • 编写Controller
@Controller
public class JsonTestController {
    /**
     * @ResponseBody 注解添加后,方法就不会走视图解析器,会直接返回一个字符串
     */
    @RequestMapping("t1")
    @ResponseBody
    public String test1() throws JsonProcessingException {
        User user = new User("nick", 26, "男");

        ObjectMapper mapper = new ObjectMapper();
        String str = mapper.writeValueAsString(user);
        return str;
    }
}

说明:

  • 如果使用@Controller会走视图解析器,如果不想返回视图,搭配@ResponseBody使用
  • 或者不使用@Controller直接使用@RestController,效果一样
  • 效果

image.png

5.2.2 JSON转换乱码

虽然配置了SpringMVC的过滤器,但是这里转JSON的时候还是会出现中文乱码,解决方案如下:

  • 方案一:原生态解决方式,在@RequestMapping中配置produces
@RequestMapping(value = "t1", produces = "application/json;charset=UTF-8")

image.png

  • 方案二:配置<mvc:annotation-driven>
<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <constructor-arg value="UTF-8"/>
        </bean>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper">
                <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                    <property name="failOnEmptyBeans" value="false"/>
                </bean>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

在其中配置一个mvc:message-converters,需要配置两个bean,分别是StringHttpMessageConverterMappingJackson2HttpMessageConverter,其中第一个类由于没有set方法,因此要使用构造器注入。

image.png

5.2.3 Date类型转换JSON

  • 通常可以使用format来先将Date类型转换成带格式的String,然后给ObjectMapper
  • 其实ObjectMapper本身就可以对时间格式进行设置,具体如下
@RequestMapping(value = "t2")
@ResponseBody
public String test2() throws JsonProcessingException {
    Date date = new Date();

    ObjectMapper mapper = new ObjectMapper();
    // ObjectMapper可以配置关闭将日期转换为时间戳
    mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
    // ObjectMapper可以配置日期格式
    mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"));
    String str = mapper.writeValueAsString(date);
    return str;
}

六、整合Mybatis

6.1 相关依赖整理

6.1.1 数据库相关

  • 数据库驱动
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.27</version>
</dependency>
  • 数据库连接池(jdbc、c3p0、D)
<dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.5.5</version>
</dependency>

6.1.2 网络相关

  • Servlet
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>
  • JSP
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>2.3.3</version>
    <scope>provided</scope>
</dependency>
  • jstl
<dependency>
    <groupId>javax.servlet.jsp.jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>

6.1.3 Mybatis相关

  • mybatis
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.9</version>
</dependency>
  • mybatis-spring
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.6</version>
</dependency>

6.1.4 SpringMVC相关

  • springmvc
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.14</version>
</dependency>
  • JDBC
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.3.14</version>
</dependency>

6.2 静态资源导出问题处理

<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
    </resources>
</build>

6.3 Mybatis准备工作

6.3.1 database.properties

jdbc.dirver = com.mysql.cj.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&useUnicode=true&characterEncoding=utf8&serverTimeZone=GMT
jdbc.user = root
jdbc.password = wang2995

6.3.2 mybatis-config.xml

  • 配置数据源(交给Spring去做)

  • 别名

  • 配置Mapper

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <package name="com.nick.pojo"/>
    </typeAliases>
</configuration>

6.4 Mapper

6.4.1 dao层编写BookMapper接口

public interface BookMapper {
    /**
     * 增加一本书
     * @param books
     * @return
     */
    int addBook(Books books);

    /**
     * 删除一本书
     * @param id
     * @return
     */
    int deleteBookById(int id);

    /**
     * 修改一本书
     * @param books
     * @return
     */
    int updateBook(Books books);

    /**
     * 查询一本书
     * @param id
     * @return
     */
    Books queryBookById(int id);

    /**
     * 查询所有书
     * @return
     */
    List<Books> queryAllBooks();
}

6.4.2 创建BookMapper.xml

Mappernamespace对应BookMapper接口

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.nick.dao.BookMapper">
    <insert id="addBook" parameterType="com.nick.pojo.Books">
        insert into books(bookName, bookCount, detail)
        values(#{bookName}, #{bookCount}, #{detail})
    </insert>
    <update id="updateBook" parameterType="com.nick.pojo.Books">
        update books
        set bookName=#{bookName}, bookCount=#{bookCount}, detail=#{detail}
        where bookID = #{bookID}
    </update>
    <delete id="deleteBookById" parameterType="java.lang.Integer">
        delete from books
        where bookID = #{bookID}
    </delete>
    <select id="queryBookById" resultType="com.nick.pojo.Books" parameterType="java.lang.Integer">
        select *
        from books
        where bookID = #{bookID}
    </select>
    <select id="queryAllBooks" resultType="com.nick.pojo.Books">
        select * from books
    </select>
</mapper>

6.4.3 将BookMapper.xml绑定到mybatis-config.xml中

<configuration>
    <typeAliases>
        <package name="com.nick.pojo"/>
    </typeAliases>
    <mappers>
        <mapper class="com.nick.dao.BookMapper"/>
    </mappers>
</configuration>

6.5 Service

6.5.1 BookService接口

实现和Dao层的接口一致

6.5.2 BookServiceImpl实现

业务层调用dao层即可

七、整合Spring层

7.1 编写spring-dao.xml

  • 关联数据库配置文件
  • 连接池
  • SQLSessionFactory
<?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"
       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-4.2.xsd">

    <!--1. 关联数据库配置文件-->
    <context:property-placeholder location="classpath:database.properties"/>

    <!--2. 连接池
    dbcp(半自动化,手动连接)
    c3p0(自动化操作,自动化加载配置文件,且自动设置到对象中)
    druid
    hikari-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.dirver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.password}"/>
        <!--c3p0私有属性-->
        <property name="maxPoolSize" value="30"/>
        <property name="minPoolSize" value="10"/>
        <property name="initialPoolSize" value="10"/>
        <!--关闭连接后不自动commit-->
        <property name="autoCommitOnClose" value="false"/>
        <!--获取连接超时时间-->
        <property name="checkoutTimeout" value="10000"/>
        <!--当获取连接失败重试次数-->
        <property name="acquireRetryAttempts" value="2"/>
    </bean>

    <!--3. sqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>

    <!--4. 配置dao接口扫描包,通过反射动态实现dao接口自动注入到Spring容器中-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--注入sqlSessionFactory-->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!--扫描要扫描的dao包-->
        <property name="basePackage" value="com.nick.dao"/>
    </bean>

</beans>

7.2 spring-service.xml

  • 扫描Service下的包
  • 将所有业务类注入到Spring中
  • 声明式事务
<?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"
       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-4.2.xsd">

    <!--1. 扫描Service下的包-->
    <context:component-scan base-package="com.nick.service"/>

    <!--2. 将所有业务层的类注入到Spring-->
    <bean id="BookServiceImpl" class="com.nick.service.BookServiceImpl">
        <property name="bookMapper" ref="bookMapper"/>
    </bean>

    <!--3. 声明式事物-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入数据源-->
        <property name="dataSource" ref="dataSource"/>
    </bean>

</beans>

八、整合SpringMVC层

8.1 web.xml

  • DispatcherServlet
  • 乱码过滤
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>encodeing</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>encodeing</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

8.2 spring-mvc.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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <context:component-scan base-package="com.nick.controller"/>
    <mvc:default-servlet-handler/>
    <mvc:annotation-driven/>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <property name="prefix" value="/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

九、整合说明

9.1 applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <import resource="classpath:spring-dao.xml"/>
    <import resource="classpath:spring-service.xml"/>
    <import resource="classpath:spring-mvc.xml"/>

</beans>

9.2 spring-dao.xml

  • 关联数据库配置文件(database.properties
  • 连接池(c3p0
  • sqlSessionFactory(数据源、配置文件路径mybatis-config.xml
    • 别名
    • mapper
  • 配置dao接口扫描包

9.3 spring-service.xml

  • 扫描Service包
  • 将所有业务层类注入Spring(BookServiceImpl
  • 声明式事务(DataSourceTransactionManager中注入数据源)

9.4 spring-mvc.xml

  • 注解驱动

  • 静态资源过滤

  • 扫描包

  • 视图解析器

9.5 编写Controller

@Controller
@RequestMapping("/book")
public class MybatisController {
    @Autowired
    @Qualifier("BookServiceImpl")
    private BookService bookService;

    @RequestMapping("/allBook")
    public String queryAll(Model model) {
        List<Books> books = bookService.queryAllBooks();
        model.addAttribute("list", books);
        return "allBook";
    }
}

十、拦截器

10.1 概述

SpringMVC的处理器拦截器类似于Servlet中过滤器Filter,用于对处理器进行预处理和后处理。

拦截器与过滤器的区别:拦截器是AOP思想的具体应用

  • 过滤器
  1. servlet规范中一部分,任何java web工程都可以使用
  2. url-pattern中配置/*之后,可以对所有要访问资源进行拦截
  • 拦截器
  1. 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
  2. 拦截器只会拦截访问的控制器的方法,如果访问的是jsp/html/css/image/js是不会拦截的

10.2 自定义拦截器

要想自定义拦截器,必须实现HandlerInterceptor接口

public class MyInterceptor implements HandlerInterceptor {
    /**
     *
     * @param request
     * @param response
     * @param handler
     * @return 为true就放行,执行下一个拦截器。如果return false
     * 就会将请求拦截,controller中的方法不会被执行
     * @throws Exception
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("==============处理前==============");
        return true;
    }
	
    /* 一般写拦截日志 */
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("==============处理后==============");
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("==============清理==============");
    }
}

配置拦截器

<!--拦截器-->
<mvc:interceptors>
    <mvc:interceptor>
        <!--包括这个请求以及下面的所有请求-->
        <mvc:mapping path="/**"/>
        <bean class="com.nick.config.MyInterceptor" id="myInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>