SpringMVC初始
以下内容如有侵权请联系删除
SpringMVC第一天
第一章 SpringMVC
1.1 MVC模式(了解)
1.2 SpringMVC介绍(理解)
第二章 SpringMVC入门案例(重点)
开发一个请求页面,向后台发送一个请求,后台需要在控制台打印一句话,然后跳转到一个新的页面
2.1 创建一个Project
略,使用Spring工程即可
2.2 创建一个新的Model加入坐标
<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 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 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、自定义一个类型转换器,实现类型转换的方法
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 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中中文乱码过滤器
<!--
配置字符集过滤器
-->
<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 文件类型(文件上传)
页面
加入文件上传的包
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
配置文件上传解析器
在SpringMVC的配置文件中添加文件解析器
<!--
文件解析器
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的配置文件中添加释放静态资源
<!--
释放静态资源的方式一
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实现异步交互(专题)
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
4.1 @RequestBody接收ajax请求
@RequestBody用于接收前端传递的请求体中的json数据,并可以自动转换封装进指定的对象中
页面
<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类
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 测试练习
页面
<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>
后台
/**
* 测试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 自定义拦截器(入门)
定义拦截器
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和方法规则)
<!--配置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一份作为第二个拦截器
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方法");
}
}
配置拦截器
<!--配置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代码
页面
<%@ 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 登录检查拦截器
当用户登录成功之后,才能够访问对应的资源。
用户已登录:正常访问
用户未登录:跳转到登录页面重新登录
自定义拦截器
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;
}
}
}
配置
<!--配置登录检查拦截器-->
<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 案例和数据库
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 创建工程
<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 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 测试
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 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 测试
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正式需要导入整合包
<!--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)
<!--开启事务注解支持-->
<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 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 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容器监听器
<!--创建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创建所有
<!--前端控制器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
也可以改为@RequestBody List<Map<String,Object> list
@RequestBody List
也可以改为@RequestBody String objects