引言
概念: 是控制层的框架,解决的是MVC分层开发中控制层的问题
优势:
1.SpringMVC是Spring体系组成的一部分,可以与Spring全家桶无缝衔接
2.SpringMVC框架从运行效率和开发效率,比Struts2高很多
作用:
1.收集参数
2.调用业务
3.流程跳转
第一个SpringMVC程序的开发
环境搭建:
1.引入相关依赖
```xml
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--javaEE规范-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<!--spring相关jar-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.2.RELEASE</version>
<scope>test</scope>
</dependency>
<!--引入springmvc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
```
2.初始化SpingMVC的核心类 (web.xml)
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<!--SpringMVC核心类相当于Struts2的核心过滤器 作用:请求转发-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--构建核心类时需要依赖与SpringMVC的配置文件 需要做初始化-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:dispatcher.xml</param-value>
</init-param>
<!--指定核心类的加载时机 Web容器启动时 加载该类
<load-on-startup>标签指定该Servlet被加载的时机
0或者大于0 意味着Tomcat启动(Web容器启动) 加载
数字越小 加载执行越早 优先级越高
小于0或者不配此标签 意味着该Servlet 使用时被加载
-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<!-- 访问后台Action中方法时,需要给该方法的url后加.do 作用:区分静态URL和访问后台Action的URL
SpringMVC_Day1/user/login.do
SpringMVC_Day1/user/register.do
静态资源
SpringMVC_Day1/css/style.css
SpringMVC_Day1/js/jwuery.js
-->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
编码步骤:
1.开发Controller
package com.baizhi.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
//自动创建控制器的对象
@Controller
public class FirstController {
/*
* 方法语法:public String 方法名 throws Exception
* 访问:SpringMVC_Day1/first.do
* 返回值:代表跳转路径
* */
@RequestMapping("/first")
public String first() throws Exception{
System.out.println("我是第一个SpringMVC程序");
//跳转到index.jsp中
return "index";
}
}
2.SpringMVC配置文件中进行配置 (只需要配置一次)
<?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 http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--告知SpringMVC框架在哪一个包下使用了对应的注解-->
<context:component-scan base-package="com.baizhi.controller"></context:component-scan>
<!--配置SpringMVC的视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!--激活URL解析器-->
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
SpringMVC语法
@RequestMapping 注解
作用: 1.指定访问的URL路径
类:相当于struts2中的namespace
方法:相当于struts2中的name
2.指定被请求的方式
method = RequestMethod.GET 指定该方法 只可以被GET方式访问
method = RequestMethod.POST 指定该方法 只可以被POST方式访问
method = {RequestMethod.GET,RequestMethod.POST}) 指定该方法 既可以被GET方式访问 又可以被POST方式访问
收集参数
1.原始的方式收集参数
2.零散变量收集参数
注意:
i.SpringMVC在接收数据时,对于8中基本类型+String进行自动类型转换
ii.当传入参数的键与接收数据的形参名不一致,可以通过@RequestParam注解解决
3.对象收集参数
注意:
1.springmvc对于日期类型转换时,只针对yyyy/MM/dd 格式进行转换
@DateTimeFormat(pattern =“yyyy-MM-dd”) 指定接收日期时的格式
再使用 type=“date” 时 默认看着为/形式 实为—形式
2.嵌套对象接收数据
4.数组或集合收集参数
解决字符集乱码问题
GET: conf/server.xml
POST:
设置字符集过滤器 web.xml
```xml
<!--过滤所有的请求 并且指定编码方式为UTF-8-->
<filter>
<filter-name>encodingFilter</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>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
```
流程跳转
Forward: 一次请求 地址栏不变 可以使用request作用域传值
Redirect: 多次请求 地址栏改变 不可以使用request作用域传值
Controller------>JSP
forward: 使用视图解析器 默认forward跳转
redirect:
Controller------->Controller
Redirect
注意:自定义跳转方式时,视图解析器将失效
传递数据
Controller---------->JSP
1.request 作用域
2.Session作用域
Controller---------->Controller
1.Forward: request作用域传递数据
2.Redirect
建议:Action跳Action时 使用Forward跳转
传递数据拓展
1.使用Model或者ModelMap替换Request作用域 (建议使用·)
好处:视图层解耦合
2.@SessionAttributes 注解的使用(了解)
作用: 可以使用@SessionAttributes注解 替换Session作用域
前提: 必须在request作用域中存储一份
使用:
@SessionAttributes(“name”) //把Request作用域中的数据转存到Session作用域中
SSM整合(SpringMVC+Spring+Mybatis)
整合思路:
环境搭建:
1.引入相关依赖
```xml
junit junit 4.11 test
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- 引入mybatis相关jar -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.8</version>
</dependency>
<!-- 引入mybatis 与 spring 整合jar -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
```
2.初始化配置 web.xml
SpringMVC:
i.解决POST方法接收数据乱码
2.配置SpringMVC核心类
```xml
encodingFilter org.springframework.web.filter.CharacterEncodingFilter encoding UTF-8 encodingFilter /*
dispatcherServlet org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:dispatcher.xml 1 dispatcherServlet *.do ```
Spring:
1.Spring的监听工厂
```xml
contextConfigLocation classpath:applicationContext.xml
org.springframework.web.context.ContextLoaderListener ```
开发步骤:
1.建表
2.写实体
3.定义DAO
4.Mapper文件实现DAO接口
5.Spring配置文件中配置mybatis的相关内容
6.定义Service接口
7.实现Service接口
@Service
@Autowire
@Transaction
8.开发控制器
package com.baizhi.action;
import com.baizhi.entity.User;
import com.baizhi.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/user")
public class UserController {
//给Service做对应的注入
@Autowired
private UserService userService;
//注册 //接收数据
@RequestMapping("/register")
public String register(User user) throws Exception{
//调用Service
userService.register(user);
//默认视图解析器
return "index";
}
}
9.SpringMVC配置文件配置
<!--告知SpringMVC框架在什么地方使用了注解-->
<contex:component-scan base-package="com.baizhi.action"></contex:component-scan>
<!--视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!--激活URL解析器-->
<mvc:annotation-driven></mvc:annotation-driven>
return "index";
}
}
9.SpringMVC配置文件配置
```xml
<!--告知SpringMVC框架在什么地方使用了注解-->
<contex:component-scan base-package="com.baizhi.action"></contex:component-scan>
<!--视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!--激活URL解析器-->
<mvc:annotation-driven></mvc:annotation-driven>
父子容器问题
解决方案:父子容器分包扫描
ModelAndView机制
作用:既可以传值又可以跳转
SpringMVC与JSON串的整合
jackson
开发步骤:
1.引入jackson的相关依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.9</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.9</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.8.9</version>
</dependency>
2.@ResponseBody
package com.baizhi.controller;
import com.baizhi.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.ArrayList;
import java.util.List;
@Controller
@RequestMapping("/json")
public class JsonController {
@RequestMapping("/tf")
@ResponseBody //自动转换为json串
public User transfer() throws Exception{
User user = new User("1", "小白", "12345", 18);
return user;
}
@RequestMapping("/tf1") //List集合
@ResponseBody //自动把返回的结果转换为json串 jackson
public List<User> transfer1() throws Exception{
List<User> users= new ArrayList<User>();
User user = new User("1", "小白", "12345", 18);
User user1 = new User("2", "小黑", "12345", 18);
User user2 = new User("3", "小红", "12345", 18);
users.add(user);
users.add(user1);
users.add(user2);
return users;
}
}
文件上传
客户端:
服务器端
2.上传文件的步骤
i.引入相关依赖
<!--文件上传jar包-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
ii.编码
package com.baizhi.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import java.io.File;
@Controller
@RequestMapping("/upload")
public class UploadController{
@RequestMapping("/u") //接收上传文件
public String upload(MultipartFile upload, HttpSession session) throws Exception{
ServletContext servletContext = session.getServletContext();
//获取目标文件夹的路径
String realPath = servletContext.getRealPath("/upload");
//获取上传文件的名字
//创建与上传文件 同名的文件 此时文件为空
File file = new File(realPath + "/" + upload.getOriginalFilename());
//把上传文件转入空的文件
upload.transferTo(file);
return "uploadOk";
}
}
iii.配置文件上传视图解析器
<!--配置文件上传的视图解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>
注意:1.创建的目标文件夹 不能为空
2.SpringMVC默认对于文件上传的大小没有限制
手工设置文件上传大小:
<!--配置文件上传的视图解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--设置文件上传大小 单位为B 10M -->
<property name="maxUploadSize" value="10240000"></property>
</bean>
文件下载
业务流程图
编码:
```java
@RequestMapping("/down") //返回值 下载的文件封装到该对象中 filename接收文件名
//5SSM整合.wmv
public ResponseEntity<byte[]> download(String filename,HttpSession session) throws Exception{
//获取目标upload的路径
ServletContext servletContext = session.getServletContext();
String realPath = servletContext.getRealPath("/upload");
//file没有则创建 有则代表此文件 5SSM整合.wmv
File file = new File(realPath + “/” + filename);
//把文件转换为字节数组
byte[] bytes = FileUtils.readFileToByteArray(file);
//设置下载时的请求头
HttpHeaders httpHeaders = new HttpHeaders();
//解决下载完成后中文乱码问题 下载时的编码
String downname = new String(filename.getBytes(“UTF-8”), “ISO-8859-1”);
//下载文件之后的打开方式
httpHeaders.setContentDispositionFormData(“attachment”,downname );
//设置下载的方式 //采用流的方式进行配置
httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
//告知SpringMVC框架状态已经准备好
return new ResponseEntity<byte[]>(bytes,httpHeaders, HttpStatus.CREATED);
}
```
全局异常处理
作用:统一管理异常 提高用户体验度
开发步骤:
1.impelements HandlerExceptionResolver 接口
```java
package com.baizhi.exception;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GlobalException implements HandlerExceptionResolver {
/*
* ModelAndView 既可以替换request作用域传递数据 又可以跳转页面
*
* */
@Override //捕捉到所有的异常
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
String message=null;
//判断异常是什么类型
if (e instanceof LoginException){
message = e.getMessage();
}else if (e instanceof RegisterException){
message=e.getMessage();
}
ModelAndView modelAndView = new ModelAndView();
//把对应的异常信息 放置在modelAndView中
modelAndView.addObject("message",message);
//跳转页面
modelAndView.setViewName("exception");
return modelAndView;
}
}
```
2.在SpringMVC配置文件中配置全局处理异常类的信息
<!--配置全局异常处理的信息-->
<bean id="e" class="com.baizhi.exception.GlobalException">
</bean>
3.准备对应的jsp
拦截器
作用: 减少控制器中冗余代码
开发步骤:
1.implements HandlerInterceptor
2.配置拦截器的相关内容
<!--配置拦截器的相关信息-->
<mvc:interceptors>
<mvc:interceptor>
<!--拦截action的路径-->
<mvc:mapping path="/ic/**"/>
<!--排除action的路径-->
<mvc:exclude-mapping path="/ic/B.do"/>
<!--具体的拦截器-->
<bean id="interceptor" class="com.baizhi.interceptor.MyInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
实战案例:强制登陆
运行流程