SpringMVC初始

以下内容如有侵权请联系删除

SpringMVC第一天

第一章 SpringMVC

1.1 MVC模式(了解)

1.2 SpringMVC介绍(理解)

第二章 SpringMVC入门案例(重点)

开发一个请求页面,向后台发送一个请求,后台需要在控制台打印一句话,然后跳转到一个新的页面

2.1 创建一个Project

略,使用Spring工程即可

2.2 创建一个新的Model加入坐标

java 复制代码
<dependencies>
    <!--springmvc-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.1.6.RELEASE</version>
    </dependency>
    <!--servlet-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
    <!--jsp-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.0</version>
      <scope>provided</scope>
    </dependency>
    <!--文件上传的包-->
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.4</version>
    </dependency>
  </dependencies>

2.3 补全目录结构

2.4 加入SpringMVC的配置文件

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd
      http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <!--1、包扫描-->
    <context:component-scan base-package="cn.itcast"></context:component-scan>

    <!--2、配置视图解析器-->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean>

    <!--3、配置SpringMVC的注解驱动-->
    <mvc:annotation-driven></mvc:annotation-driven>

</beans>

2.5 加入web的配置文件

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://java.sun.com/xml/ns/javaee"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
       version="2.5">

   <!--
      配置前端控制器
         DispatcherServlet
   -->
   <servlet>
      <servlet-name>mvc</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <!--自动加载Springmvc的配置文件-->
      <init-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>classpath:springmvc.xml</param-value>
      </init-param>
   </servlet>


   <servlet-mapping>
      <servlet-name>mvc</servlet-name>
      <!--
         处理所有请求
         不处理.jsp为后缀的请求
      -->
      <url-pattern>/</url-pattern>
   </servlet-mapping>
</web-app>

2.6 开启请求页面

2.7 开发控制器

2.8 开发响应页面

2.9 部署测试

第三章 SpringMVC原理

3.1 工作流程


3.2 SpringMVC的三大组件


配置

java代码

第四章 RequestMapping(重点)

4.1 限制请求路径(value path)

value和path属性是一模一样的,都是配置当前方法的请求路径

页面

和之前一模一样

后台

4.2 限制请求类型(method)

method :配置当前请求的请求类型(post,get,delete,put)

页面

后台

4.3 限制请求参数(params)

params:配置此方法比如携带的请求参数。如果没有指定参数,抛出异常

页面

后台

第五章 接收请求参数(重点)

5.1 简单类型(常用)

只需要保证前端传递的参数名称跟方法的形参名称一致就好

页面

后台

5.2 对象类型(常用)

只需要保证前端传递的参数名称跟pojo的属性名称(set方法)一致就好

页面

封装一个实体

后台

5.3 数组类型

只需要保证前端传递的参数名称跟方法中的数组形参名称一致就好

页面

后台

5.4 集合类型(了解)

将前端传入的数据自动的封装成集合,需要将集合包装到一个对象中才行。获取集合参数时,要将集合参数包装到一个实体中才可以

页面

封装一个Vo对象

后台

5.5 日期类型

对于一些常见的类型, SpringMVC是内置了类型转换器的,但是对于一些格式比较灵活的参数(日期时间),SpringMVC无法完成类型转换.

SpringMVC对日期:yyyy/MM/dd.

这时候就必须自定义类型转换器

页面

自定义时间类型转换器(面试)

1、自定义一个类型转换器,实现类型转换的方法

java 复制代码
package cn.itcast.converter;

import org.springframework.core.convert.converter.Converter;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 日期类型转化器:
 *  将输入的String字符串,按照自定义的规则转化为date对象
 *  1、实现Converter接口,并提供泛型
 *  2、实现convert方法,进行类型转化
 */
public class StringToDateConverter implements Converter<String, Date> {

    @Override
    public Date convert(String s) {
        Date date = null;

        try {
            date = new SimpleDateFormat("yyyy-MM-dd").parse(s);
        }catch (Exception e) {
            e.printStackTrace();
        }
        return date;
    }
}

2、将自定义的类型转换注册到SpringMvc的转换服务中,然后再将服务注册到SpringMVC的注解驱动

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd
      http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <!--1、包扫描-->
    <context:component-scan base-package="cn.itcast"></context:component-scan>

    <!--
        2、配置视图解析器
              将逻辑视图转化为物理视图
              主要功能,自动的对返回的逻辑试图添加前缀和后缀
              前缀 + 逻辑视图  + 后缀
    -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--配置返回路径的前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <!--后缀-->
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!--配置类型转化器 : 将自定义的类型转化器加入到SpringMVC的类型转化器集合中-->
    <bean id="conversionService2" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="cn.itcast.converter.StringToDateConverter"></bean>
            </set>
        </property>
    </bean>

    <!--3、配置SpringMVC的注解驱动
            相当于配置了增强版的处理器映射器和处理器适配器
    -->
    <mvc:annotation-driven conversion-service="conversionService2"></mvc:annotation-driven>

</beans>

后台

5.6 中文乱码

SpringMVC在使用post提交请求时,对于中文参数是有乱码问题的,针对这种情况它提供了一个中文乱码过滤器,我们只需要进行配置一下就可以了

在web.xml配置SpringMVC中中文乱码过滤器

xml 复制代码
<!--
   配置字符集过滤器
-->
<filter>
   <filter-name>characterEncodingFilte</filter-name>
   <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
   <!--指定编码-->
   <init-param>
      <param-name>encoding</param-name>
      <param-value>utf-8</param-value>
   </init-param>
</filter>

<filter-mapping>
   <filter-name>characterEncodingFilte</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

5.7 文件类型(文件上传)

页面

加入文件上传的包

xml 复制代码
<dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.4</version>
</dependency>

配置文件上传解析器

在SpringMVC的配置文件中添加文件解析器

xml 复制代码
<!--
    文件解析器
        id:固定值(multipartResolver)
        其中指定上传文件的大小规则
-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--文件的大小规则  5M = 1024 * 1024 * 5 -->
        <property name="maxUploadSize" value="5242880"></property>
    </bean>

后台

5.8 @RequestParam

第六章 接收请求头信息(了解)

SpringMVC第二天

第一章 页面跳转之转发

请求转发:只发送一起请求,不会丢失数据(SpringMVC的默认页面跳转形式)

1.1 获取Servlet原生API

Servlet原生API对象: HttpServletRequest,HttpSevletResponse,HttpSession

语法规则:
1、将对象已方法参数的形式配置到controller方法中
2、将需要的API对象通过@Autowired的方式注入进来

通过第二种方式引入API对象,说白了,就是将API对象从局部变量抽取成成员变量。但是此时就特别像卖票案例,会引发线程安全问题。什么意思呢?一次请求就是一个线程,多次请求,就是并发的线程,多个线程同时访问同样的API对象(成员对象)就会引发线程安全问题。Spring框架是如何避免的呢?通过ThreadLocal避免.

当前端控制器接收到一次请求时,也就是一个线程,前端控制器本质是一个Servlet,前端控制器会获取request对象,然后利用ThreadLocal技术,将request对象绑定到当前线程上,方便后面的组件使用request对象。当前端控制再次接收到请求时,会再次获取request对象,再次通过ThreadLocal技术再次给新的线程绑定。说白了,每次请求(线程)都会绑定,也就是说线程使用的API对象都是不同的,并不是同一个,所以不会引发线程安全问题。

通过第二种方式使用response会抛出异常,因为SpringMVC是通过请求获取request对象,利用ThreadLocal技术绑定到线程上,而response是响应,此时还没有响应,不可能通过请求得到response对象,所以通过第二种方式使用response会抛出异常。(只有获得response对象有此异常,获取其他对象没有此异常)

如何解决呢?如下代码就可以解决。在某个方法的参数中,写入response对象,就相当于给response对象赋值,就可以解决第二种方式的异常。

环境准备
练习获取Servlet对象


1.2 方式一:简单方式(推荐***)

1.3 方式二:使用forward转发(推荐**)

页面
后台

1.4 方式三:使用servlet原生api(了解)

1.5 转发时携带数据(重点)

绑定Request域(推荐)


绑定到Model对象(了解)
通过ModelAndView返回(官方)

第二章 页面跳转之重定向

2.1 方式一:使用redirect重定向(推荐)

页面
后台

2.2 方式二:使用servlet原生API(了解)

第三章 释放静态资源

3.1 方式一

在Springmvc的配置文件中添加释放静态资源

xml 复制代码
<!--
    释放静态资源的方式一
        mapping : 请求路径的URL的映射规则
        location: 静态资源的物理目录
        当静态资源请求到SpringMVC的前端控制器时,根据释放资源的配置
            1、不在查找具体的controller处理
            2、从location路径中查找匹配的资源
-->
<mvc:resources mapping="/js/*" location="/js/"></mvc:resources>
<mvc:resources mapping="/image/*" location="/image/"></mvc:resources>
<mvc:resources mapping="/css/*" location="/css/"></mvc:resources>

配置繁琐,所有的静态资源分门别类放置到不同的文件夹,一个一个进行配置

3.2 方式二(推荐)

3.3 方式三(掌握)


第三种方式:只有请求以.do结尾的才可以进入springMVC前端控制器,不是以.do结尾的交给tomcat默认的servlet。

第四章 Ajax+json实现异步交互(专题)


xml 复制代码
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.9.8</version>
</dependency>

4.1 @RequestBody接收ajax请求

@RequestBody用于接收前端传递的请求体中的json数据,并可以自动转换封装进指定的对象中

页面

html 复制代码
<br>
<hr>
<h4>测试SpringMVC中的ajax处理</h4>
<input type="button" value="测试SpringMVC中的ajax处理" onclick="sendAjsx()">
<script>
    function sendAjsx() {
        $.ajax({
            type: "POST",
            url: "${pageContext.request.contextPath}/hello/demo7",
            contentType: "application/json;charset=utf8",
            dataType: "json",
            data: '{"name":"张三","age":18}',
            success: function (data) {
                console.log(data);
            }
        });
    }
</script>

封装一个User类

java 复制代码
package cn.itcast.domain;

public class User {

    private String name;

    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

后台

4.2 @ResponseBody返回json数据

@ResponseBody用于将controller方法返回的对象通过转换器转换为指定的格式(通常为json)之后,写入到response对象的body区
后台

4.3 @ResponseBody解释补充

SpringMVC中,如果Controller的方法返回值没有@ResponseBody,并且方法的返回值类型不是String类型,会报Unknown return value type异常。因为返回值会经过视图解析器,视图解析器无法解析除String类型以外的类型,所以会报异常。如果加上了@ResponseBody注解,不经过视图解析器。

@ResponseBody的作用相当于原生servlet中的response.getWriter().write(json);


第五章 Restful风格(专题)

Restful风格: SpringBoot课程基础

5.1 什么是restful风格

5.2 测试练习

页面

html 复制代码
<h4>测试restFul风格的URL</h4>
<form action="${pageContext.request.contextPath}/user" method="post">
    <input type="submit" value="模拟post请求">
</form>
<a href="${pageContext.request.contextPath}/user">模拟get请求</a>

后台

java 复制代码
/**
 * 测试Restful编程风格
 *  1、对同一个URL,根据不同的请求方式,完成不同的业务处理
 *  2、请求URL上存在,地址参数 /user/{id}
 *
 *  /user
 *      保存      :post
 *      查询所有  :get
 *  /user/{id}
 *      根据id查询用户
 *      删除用户
 *      根据id更新用户
 */
@Controller
public class UserController {


    //保存
    @RequestMapping(value = "/user",method = RequestMethod.POST)
    public String saveUser() {
        System.out.println("保存用户");
        return "success";
    }


    //查询所有
    @RequestMapping(value = "/user",method = RequestMethod.GET)
    public String findAll() {
        System.out.println("查询所有用户");
        return "success";
    }


    /**
     * 根据id查询用户
     *  传入地址参数:
     *      请求URL  /user/1
     *      地址参数: {自定义参数名}
     *      在java方法中如何获取地址参数中的数据
     *          @PathVariable : 配置到方法参数上
     *              自动的从地址参数中,根据名称获取参数值
     *              @PathVariable("自定义的参数名")
     *
     */
    //@RequestMapping(value = "/user/{id}",method = RequestMethod.GET)
    @GetMapping(value="/user/{id}")
    public String findById(
            @PathVariable(value="id") Integer userId) {
        System.out.println("根据id查询用户userId="+userId);
        return "success";
    }

    //根据id更新 :put
    //@RequestMapping(value = "/user/{id}",method = RequestMethod.PUT)
    @PutMapping(value = "/user/{id}")
    public String update(
            @PathVariable(value="id") Integer userId) {
        System.out.println("根据id更新用户userId="+userId);
        return "success";
    }

    //根据id删除 :delete
    @RequestMapping(value = "/user/{id}",method = RequestMethod.DELETE)
    public String delete(
            @PathVariable(value="id") Integer userId) {
        System.out.println("根据id删除用户userId="+userId);
        return "success";
    }

    //传递多参数
    @RequestMapping(value = "/user/{page}/{size}",method = RequestMethod.GET)
    public String find(@PathVariable(value = "page") Integer page,@PathVariable(value = "size") Integer size) {
        System.out.println(page);
        System.out.println(size);
        return "success";
    }
}

5.3 什么是RESTful风格

什么是RESTful风格?

一、概述(百度百科)

REST(英文:Representational State Transfer,简称REST)

一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

二、什么是RESTful

REST 指的是一组架构(约束条件)和原则。满足这些(约束条件)和(原则)的应用程序或设计就是 RESTful。

三、restful有什么特点

1.每一个URI代表一种资源,独一无二

2.客户端和服务器之间,传递这种资源的某种表现层

3.客户端通过四个HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"。

四、具体用例

我们都知道在没有出现RESTful风格之前,我们的代码是这样的。

第六章 异常处理机制(专题)


6.1 方式一:自定义异常处理器

自定义异常处理器

异常页面编写

6.2 方式二:@ControllerAdvice

SpringMVC第三天

第一章 拦截器(重点)

1.1 什么是拦截器(重点)

1.2 自定义拦截器(入门)

定义拦截器

java 复制代码
package cn.itcast.interceptors;


import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 自定义拦截器
 *  实现HnadlerInterceptor接口
 *  实现其中的三个方法(三个拦截点)
 */
public class MyInterceptor01 implements HandlerInterceptor {


    /**
     * 进入controller方法之前执行的内容(对请求拦截处理)
     * 返回值 boolean
     *  true   : 放行(继续向后执行,进入到controller)
     *  false  : 拦截过滤
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("执行MyInterceptor01的preHandle方法");
        return true;
    }


    /**
     * 执行了controller方法之后,执行的内容(对象响应进行拦截处理)
     */
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("执行MyInterceptor01的postHandle方法");
    }


    /**
     * 页面渲染完成之后,执行(不用)
     */
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("执行MyInterceptor01的afterCompletion方法");
    }
}

配置拦截器

在SpringMVC的配置文件中,添加拦截器配置(配置拦截器对应需要拦截的URL和方法规则)

xml 复制代码
<!--配置SpringMVC的拦截器-->
<mvc:interceptors>
    <!--配置具体的拦截器和拦截器的拦截规则-->
    <mvc:interceptor>
        <!--
            mapping : 配置拦截规则
            /** 表示拦截所有
            请求  /hello/demo1
        -->
        <mvc:mapping path="/**"/>
        <!--
            exclude-mapping: 配置不拦截的规则
        -->
        <mvc:exclude-mapping path="/hello/demo2"/>
        <!--创建对象:在当前拦截器中有效-->
        <bean class="cn.itcast.interceptors.MyInterceptor01"></bean>
    </mvc:interceptor>
</mvc:interceptors>

1.3 自定义拦截器链

开发中拦截器可以单独使用,也可以同时使用多个拦截器形成一条拦截器链。

开发步骤和单个拦截器是一样的,只不过注册的时候注册多个,注意这里注册的顺序就代表拦截器执行的顺序。

开发拦截器

从第一个拦截器Copy一份作为第二个拦截器

java 复制代码
package cn.itcast.interceptors;


import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 自定义拦截器
 *  实现HnadlerInterceptor接口
 *  实现其中的三个方法(三个拦截点)
 */
public class MyInterceptor02 implements HandlerInterceptor {


    /**
     * 进入controller方法之前执行的内容(对请求拦截处理)
     * 返回值 boolean
     *  true   : 放行(继续向后执行,进入到controller)
     *  false  : 拦截过滤
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("执行MyInterceptor02的preHandle方法");
        return true;
    }


    /**
     * 执行了controller方法之后,执行的内容(对象响应进行拦截处理)
     */
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("执行MyInterceptor02的postHandle方法");
    }


    /**
     * 页面渲染完成之后,执行(不用)
     */
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("执行MyInterceptor02的afterCompletion方法");
    }
}

配置拦截器

xml 复制代码
<!--配置SpringMVC的拦截器-->
<mvc:interceptors>
    <!--配置具体的拦截器和拦截器的拦截规则-->
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <mvc:exclude-mapping path="/hello/demo2"/>
        <bean class="cn.itcast.interceptors.MyInterceptor01"></bean>
    </mvc:interceptor>

    <!--配置具体的拦截器和拦截器的拦截规则-->
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <mvc:exclude-mapping path="/hello/demo2"/>
        <bean class="cn.itcast.interceptors.MyInterceptor02"></bean>
    </mvc:interceptor>
</mvc:interceptors>

多个拦截器链的执行顺序和配置顺序有关

1.4 拦截器和过滤器的区别(面试)

过滤器是Servlet规范中的一部分,任何java web工程都可以使用。

拦截器是SpringMVC框架的,只有使用了SpringMVC框架的工程才能用。

过滤器在url-pattern中配置了/*之后,可以对所有要访问的资源拦截。

拦截器只会拦截访问的控制器方法,如果访问的是jsp,js,html,css,image等,它是不拦截的。

第二章 登录检查拦截器(重点)

需求:

  • 用户访问查询所有请求(用于已登录可以访问,没有登录不能访问)
  • 如果用户已经登录,即可成功访问
  • 如果用户没有登录,不允许访问,返回登录页面login.jsp重新登录

2.1 搭建环境

2.2 查询所有功能实现

Controller代码

页面

2.3 登录功能实现


Controller代码

页面

html 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>用户登录</title>
    </head>
    <body>
        <h3>欢迎登录传智播客</h3>
        
        <%--
            /login
                name=admin
                password=admin
        --%>
        <form action="${pageContext.request.contextPath}/login" method="post">
            用户名:<input type="text" name="name"><br>
            密码:<input type="text" name="password"><br>
            <input type="submit" value="登录"><br>
        </form>
    </body>
</html>

2.4 登录检查拦截器

当用户登录成功之后,才能够访问对应的资源。

用户已登录:正常访问

用户未登录:跳转到登录页面重新登录

自定义拦截器

java 复制代码
package cn.itcast.interceptors;


import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * 登录检查拦截器
 */
public class LoginInterceptor implements HandlerInterceptor {

    /**
     *  进入到controller方法之前的拦截点(登录检查)
     *  需求:
     *      当用户已登录,执行后续请求(放行)
     *      当用户未登录,不执行后续请求(重定向到登录页面)
     *  返回值:
     *      true:放行
     *      false:拦截处理
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
        Object user = session.getAttribute("user"); //获取登录用户
        //1、判断用户是否登录
        if(user != null) {
            //1.1 如果以登录放行
            return true;
        }else {
            //1.2 未登录,(重定向到登录页面)拦截
            response.sendRedirect(request.getContextPath() + "/login.jsp");
            return false;
        }
    }
}

配置

xml 复制代码
<!--配置登录检查拦截器-->
<mvc:interceptors>
    <mvc:interceptor>
        <!--对所有的请求都会拦截,对于登录动作-->
        <mvc:mapping path="/**"/>
        <!--放行登录-->
        <mvc:exclude-mapping path="/login"/>
        <bean class="cn.itcast.interceptors.LoginInterceptor"></bean>
    </mvc:interceptor>
</mvc:interceptors>

2.5 测试

第三章 SSM整合(练习)

3.1 整合的意义

借助Spring框架,完成对象的创建和依赖注入。通过Spring的声明式事务完成Service层的事务控制

3.2 整合的步骤

SSM整合:将一切交Spring管理(mybatis,springmvc)

整合步骤(初学者)∶

  • 搭建mybatis的运行环境(保证mybatis可以独立运行)
  • 搭建Spring的运行环境(IOC)
  • 整合Spring和mybatis
  • 搭建Springmvc的运行环境
  • 整合Spring和SpringMVC
  • 整合:不是重点(会copy,看懂,会改,会抄)

第四章 搭建Mybatis运行环境

4.1 案例和数据库

sql 复制代码
CREATE TABLE `user` (
  `id` int(11) NOT NULL auto_increment,
  `password` varchar(32) NOT NULL COMMENT '密码',
  `username` varchar(32) NOT NULL COMMENT '用户名称',
  `birthday` datetime default NULL COMMENT '生日',
  `sex` char(1) default NULL COMMENT '性别',
  `address` varchar(256) default NULL COMMENT '地址',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*Data for the table `user` */

insert  into `user`(`id`,`username`,`password`,`birthday`,`sex`,`address`) values (41,'老王','111111','2018-02-27 17:47:08','男','北京'),(42,'小二王','111111','2018-03-02 15:09:37','女','北京金燕龙'),(43,'小三王','111111','2018-03-04 11:34:34','女','北京金燕龙'),(45,'传智播客','111111','2018-03-04 12:04:06','男','北京金燕龙'),(46,'老王','111111','2018-03-07 17:37:26','男','北京'),(48,'小马宝莉','111111','2018-03-08 11:44:00','女','北京修正');

4.2 创建工程

xml 复制代码
<dependencies>

        <!--mybatis相关的坐标-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.1</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>


        <!--Spring相关坐标-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.15</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.1.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.7</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.1.6.RELEASE</version>
        </dependency>

        <!--springMVC相关坐标-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <!--mybatis对接Spring的整合包-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.1</version>
        </dependency>
    </dependencies>

4.3 创建实体类

4.4 创建Dao接口

4.5 创建Dao的映射文件

4.6 创建Mybatis的核心配置文件

xml 复制代码
<?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="cn.itcast.domain"/>
    </typeAliases>

    <!--
        环境配置:数据源
    -->
    <environments default="env">
        <environment id="env">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///spring"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>

    <!--映射文件-->
    <mappers>
        <package name="cn.itcast.dao"/>
    </mappers>

</configuration>

4.7 测试

java 复制代码
package cn.itcast.test;

import cn.itcast.dao.UserDao;
import cn.itcast.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class MybatisTest {

    public static void main(String[] args) throws IOException {
        //1、加载mybatis的核心配置文件
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        //2、创建SqlSessionFactoryBuilder
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //3、创建SqlSessionFactory
        SqlSessionFactory sessionFactory = builder.build(is);
        //4、创建SqlSession
        SqlSession sqlSession = sessionFactory.openSession();
        //5、创建Dao接口的动态代理对象
        UserDao userDao = sqlSession.getMapper(UserDao.class);//dao接口
        //6、测试dao接口方法
        List<User> list = userDao.findAll();
        for (User user : list) {
            System.out.println(user);
        }
        //7、释放资源
        sqlSession.close();
    }
}

第五章 搭建Spring运行环境

Spring运行环境:IOC环境(将对象存入Spring容器,从容器中获取对象)

使用XML+注解注解的形式配置

  • 开启注解支持(包扫描)
  • 自定义的java对象(注解)
  • 第三方jar包中的java对象(XML)

5.1 创建service接口

5.2 创建service接口实现类

5.3 Spring配置

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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--配置方式: xml + 注解-->

    <!--包扫描-->
    <context:component-scan base-package="cn.itcast.service"></context:component-scan>
</beans>

5.4 测试

java 复制代码
package cn.itcast.test;

import cn.itcast.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class SpringTest {

    @Autowired
    private UserService userService;

    @Test
    public void testFindAll() {
        userService.findAll();
    }
}

第五章 整合Mybatis与Spring

5.1 整合的思路

将mybatis中用到的核心对象,交给spring容器管理。在service配置事务管理mybatis和Spring正式需要导入整合包

xml 复制代码
<!--mybatis对接Spring的整合包-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.1</version>
        </dependency>

5.2 在Spring配置文件中配置整合

(1)Spring管理mybatis的核心对象(SqlSessionFactory)

  • 替换mybatis的核心配置文件
  • 数据源,SqlsessionFactory,映射文件

(2)事务配置

  • 事务管理器
  • xml+注解(@Transcational)
xml 复制代码
<!--开启事务注解支持-->
<tx:annotation-driven></tx:annotation-driven>
<!--Spring整合mybatis-->
<!--数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="username" value="root"></property>
    <property name="password" value="root"></property>
    <property name="url" value="jdbc:mysql:///heima31"></property>
    <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
</bean>

<!--Sqlsessionfactory: 配置具体实现 SqlsessionfactoryBean-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"></property>
    <!--别名包-->
    <property name="typeAliasesPackage" value="cn.itcast.domain"></property>
</bean>

<!--
    映射文件
        映射文件扫描器。功能
            1、当Spring容器启动的时候,会找到此配置,读取配置文件和dao接口所在的包
            2、spring自动的扫描指定包下的所有dao接口
            3、Spring自动的根据动态代理创建dao接口的实现(动态代理对象)
            4、将动态代理对象,存入Spring容器
 -->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <!--dao接口和映射文件所在的包-->
    <property name="basePackage" value="cn.itcast.dao"></property>
</bean>


<!--Spring中的事务管理-->
<!--事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>

5.3 service中注入dao的依赖

第六章 搭建SpringMVC运行环境

测试:进行页面跳转即可

6.1 转化工程

6.2 配置SpringMVC的配置文件

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd
      http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <!--SpringMVC的配置文件-->

    <!--1.controller的包扫描-->
    <context:component-scan base-package="cn.itcast.controller"></context:component-scan>

    <!--2.视图解析器-->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!--3.mvc的驱动-->
    <mvc:annotation-driven></mvc:annotation-driven>

    <!--4.释放静态资源-->
    <mvc:default-servlet-handler></mvc:default-servlet-handler>


</beans>

6.3 配置web.xml的配置文件

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://java.sun.com/xml/ns/javaee"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
       version="2.5">

   <!--前端控制器dispatcherServlet-->
   <servlet>
      <servlet-name>mvc</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>classpath:springmvc.xml</param-value>
      </init-param>
   </servlet>
   <servlet-mapping>
      <servlet-name>mvc</servlet-name>
      <url-pattern>/</url-pattern>
   </servlet-mapping>

   <!--中文乱码的过滤器 CharacterEncodingFilter-->
   <filter>
      <filter-name>characterEncodingFilter</filter-name>
      <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
      <init-param>
         <param-name>encoding</param-name>
         <param-value>utf-8</param-value>
      </init-param>
   </filter>
   <filter-mapping>
      <filter-name>characterEncodingFilter</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>


</web-app>

6.4 创建控制器UserController

6.5 页面

第七章 整合SSM

整合的主要目的:将Spring容器的对象,和SpringMVC容器中的对象整合到一起。

7.1 父子容器

7.2 配置Spring容器监听器

xml 复制代码
<!--创建Spring容器的监听器,tomcat启动成功之后,加载指定的Spring配置文件-->
<listener>
   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--指定Spring加载的配置文件-->
<context-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>classpath:applicationContext.xml</param-value>
</context-param>

配置listener就是7.1的父子容器,当tomcat启动时,会加载spring容器,当运行DispatcherServlet会加载springMVC容器,spring容器是父容器,springMVC容器是子容器,在配置包扫描时,一定要注意,spring容器中的包扫描时cn.itcast;而springmvc容器中的包扫描是cn.itcast.controller。从包扫描也可以看出父子容器的概念。

7.3 通过MVC创建所有

xml 复制代码
<!--前端控制器dispatcherServlet-->
<servlet>
   <servlet-name>mvc</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml,classpath:applicationContext.xml</param-value>
   </init-param>
</servlet>

7.3的方式不会有父子容器的概念,会把所有的对象记载到springMVC容器。

如上图,上图是tomcat的运行流程,当tomcat启动会后,会根据web.xml配置文件加载springmvc.xml配置文件,也就是springmvc容器,但是无法记载spring容器,当没有加载spring容器,也会报异常(Error creating bean with name 'userServiceImpl': Unsatisfied dependency expressed through field 'userDao'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'cn.itcast.dao.UserDao' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

),

报此异常的原因就是没有加载spring容器,加载spring容器有两种方法,第一种就是spring容器监听器,第二种就是加载applicationContext.xml配置文件。

bug

1、先说/是什么意思

在刚开始学习dispatcherservlet(前端控制器)的时候,配置的"/"我一直不知道是什么意思。如上图,不处理.jsp为后缀的请求,意思是不拦截.jsp为后缀的请求。但是dispatcherservlet如果没有配置释放静态资源,会拦截。什么意思呢?

如果一个请求是以.jsp为结尾的,springMVC不处理,可以理解为不进入dispatcherservlet,直接按照url路径,返回给指定访问的jsp页面。

但是如果是一些静态资源,例如js,css等,会进入dispatcherservlet进行处理,进入dispatcherservlet后,会调用处理器映射器,但是处理器映射器又找不到相应的controller来处理,因此报错。

在学习springmvc第二天的第三章释放静态资源的时候,如上图,图中写到/,代表处了jsp请求不拦截,其他的所有请求都会拦截,包括一些静态文件。这句话的意思就是jsp请求不进入dispatcherservlet处理,直接根据url返回jsp页面,其他的请求会进入dispatcherservlet处理。

除了jsp请求,其他请求都会进入dispatcherservlet(也就是说,除了jsp请求,dispatcherservlet会拦截所有请求),但是静态资源的请求又没有相应的controller处理,所以就有了第三章释放静态资源的三种方式。

2、再说拦截器

如上图,写明了如果访问的是静态资源,拦截器不会拦截,但是根据实际代码,拦截器会进行拦截。

老师讲解拦截器拦截过程

当请求进入到dispatcherservlet中,会先到拦截器,然后会到处理器映射器,根据处理器映射器找到相应的controller处理,如果没有找到controller,委托给默认default servlet处理(委托的前提是配置静态资源释放)。

拦截器在dispatcherservlet后面,即使配置了静态资源释放,但由于拦截器拦截了静态资源请求,所以导致静态资源请求失败。所以,如果有拦截器,并且配置了如下图,会导致拦截器拦截静态资源,即使配置了释放静态资源,也毫无用处。

如上图,也写明了如果访问的是静态资源,拦截器不会拦截,但是根据实际代码,拦截器会进行拦截。

解决拦截器拦截静态资源有如下两种方式:

第一种

第二种

在springmvc.xml中添加

在web.xml中添加

过滤器和拦截器执行顺序

3、建议使用方式三

如上图,使用方式三就不会出现拦截器拦截静态资源,配置简单,建议使用方式三(因为方式三只处理以.do结尾的请求,如果不是以.do结尾的,根本不会进入到前端控制器,所以就不会出现拦截器拦截静态资源)。

传参

@RequestParam与@RequestBody的使用

@RequestParam使用方法:

@RequestParam一般与get连用。

@RequestParam如果与post连用,则Content-Type的值必须为application/x-www-form-urlencoded或者mutipart/form-data

@RequestBody使用方法:

@RequestBody与post连用,@RequestBody接口前端类型的值为json格式,封装成对象。

前端传递的json串用post请求发送,如果用get请求会失败,因为get请求拼接url一般不包含大括号等特殊字符。











一般来说,@RequestParam是与get请求连用的,@RequestBody是与post连用的,为什么这么说呢?@RequestParam翻译一下是请求参数,@RequestBody翻译一下是请求体,一般来说对于常见的浏览器发出的请求,get请求是有请求参数没有请求体,而post请求是有请求体的。@RequestParam是针对请求参数的注解,而@RequestBody是针对请求体中的json封装到对象上,所以@RequestParam通常与get请求连用,而@RequestBody通常与post请求连用。

@RequestBody不会与get请求连用,因为如果使用@RequestBody,前端发送的类型一定是json串,如果使用get请求传递json串,会失败。因为get请求拼接url不允许包括大括号等字符,所以@RequestBody与post连用

传参问题

使用post请求,参数上什么注解都没有,变为url传参

使用post请求,参数上使用@RequestParam,变为url传参

POST与@RequestBody连用传参

@RequestBody String example



@RequestBody List example



@RequestBody BxmRuleInfo example



@RequestBody BxmRuleInfo example

也可以改为@RequestBody Map<String,Object> example

@RequestBody List list



@RequestBody List list

也可以改为@RequestBody List<Map<String,Object> list

@RequestBody List list

也可以改为@RequestBody String objects


相关推荐
Cyan_RA91 个月前
SpringMVC @RequestMapping的使用演示和细节 详解
java·开发语言·后端·spring·mvc·ssm·springmvc
Cyan_RA91 个月前
SpringMVC 执行流程分析 详解(图解SpringMVC执行流程)
java·人工智能·后端·spring·mvc·ssm·springmvc
FrankYoou1 个月前
Spring Boot + Spring MVC 项目结构
spring boot·spring·springmvc
FrankYoou2 个月前
Spring MVC + JSP 项目的配置流程,适合传统 Java Web 项目开发
java·spring·springmvc
YDS8292 个月前
SpringMVC —— Spring集成web环境和SpringMVC快速入门
java·spring·mvc·springmvc
_码农121382 个月前
简单练习Spring MVC REST风格的代码
springmvc
尚学教辅学习资料2 个月前
SSM从入门到实战:3.2 SpringMVC请求处理与控制器
spring·ssm·springmvc
郑州吴彦祖7722 个月前
Spring MVC快速入门
spring·springmvc
Resean02233 个月前
SpringMVC 6+源码分析(二)DispatcherServlet实例化流程 1
java·spring boot·spring·servlet·springmvc