SpringMVC:
SpringMVC简介:
- SpringMVC是基于Spring的一个框架 , 实际上就是spring的一个模块 , 专门是做web开发的 , 是servlet的升级版
- web开发底层就是Servlet , 框架是在servlet基础之上加入一些功能 , 让你做web开发方便 ,
- springMVC就是一个Spring , spring就是一个容器 , ioc能够管理对象 , 使用 , @Component , @Repository , @Service , @Controller
- SpringMVC能够创建对象 , 放入到容器中(SpringMVC容器) , Springmvc容器中放的是控制器对象 ,
我们要做的就是 : 使用@Controller创建对象 , 把对象放入到Springmvc容器中 , 把创建的对象作为控制器使用 , 这个控制器对象能够接收用户的请求 , 显示处理结果 , 就当做是一个servlet使用
使用**@Controller 注解创建的是一个普通类的对象** , 不是servlet , SpringMVC赋予了控制器对象一些额外的功能
web开发底层是servlet , springmvc中有一个对象是servlet : DispatherServlet(中央调度器)
DispatcherServlet : 负责接收用户的所有请求 , 用户把请求给了DispatcherServlet, 之后 , DispatcherServlet把请求转发给我们的Controller对象 , 最后是Controller对象处理请求
SpringMVC优点 :
- 1.基于MVC架构 ,
- 功能分工明确 , 解耦合
- 2.容易理解 , 上手快 , 解耦合
- 就可以开发一个注解的SpringMVC项目 , SpringMVC也是轻量级的 , jar很小 , 不依赖特定的接口和类
- 3.作为Spring框架的一部分 , 能够使用Spring的 IOC , 和AOP , 方便整合Strtus , MyBatis , Hibernate , JPA等其他框架
- 4.SpringMVC强化注解的使用 , 在控制器 , Service , Dao都可以使用注解 , 方便灵活 ,
- 使用@Controller创建处理器对象 , @Service创建业务对象 , @Autowired 或者 @Resource在控制器类中注入Service , Service类中注入Dao
SpringMVC快速入门:
- 配置SpringMVC核心控制器DispatcherServlet , 在web.xml文件中配置
<!--配置spring-mvc的前端控制器-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--设置服务器启动的时候就去加载控制器-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<!--设置/ 表示所有的请求都会通过这个控制器-->
<url-pattern>/</url-pattern>
</servlet-mapping>
- 创建Controller类和视图页面 , 并且配置业务方法的映射地址
@Controller
public class UserController {
//请求映射
@RequestMapping("/save")
public String save(){
System.out.println("Controller save Running...");
//return 直接就是对应的资源文件
return "success.html";
//这里默认的就是转发的方式 , 如果想要使用重定向 , 就要在访问路径前边加上一个 , redirect:
}
}
- 配置Spring-MVC的核心配置文件 spring-mvc.xml
- 使用的是spring的主配置文件模板
<!--Controller的组件扫描-->
<context:component-scan base-package="controller"/>
- 在上边的xml文件中的前端控制器中 , 配置初始化参数 : 将spring-mvc.xml文件加载进去
<!--配置spring-mvc的前端控制器-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--设置初始化参数 , 在创建前端控制器的时候 , 加载spring-mvc的主配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!--设置服务器启动的时候就去加载控制器-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<!--设置/ 表示所有的请求都会通过这个控制器-->
<url-pattern>/</url-pattern>
</servlet-mapping>
SpringMVC注解解析:
@Controller :
@RequestMapping : 请求映射
用于建立请求URL与处理请求方法之间的对应关系
位置 :
类上 : 请求URL的第一级访问目录 , 此处不写的话 , 就相当于应用的根路径
方法上 : 请求URL的第二级访问目录 , 与类上使用@RequestMapping标注的一级目录一起组成访问虚拟路径
属性 :
value : 用于指定请求的URL , 它和path属性的作用是一样的
method : 用于指定请求的方式
params : 用于指定限制请求参数的条件 , 它支持简单的表达式 , 要求请求参数的key和value必须和配置的一模一样
- 例如 : params = {“accountName”} , 表示请求参数必须有accountName
- params = {“money!100”} 表示请求参数中money不能是100
@Controller
@RequestMapping("/user")//一级访问
public class UserController {
//请求映射 , 如果类上边没写这个注解 , 那么访问路径就是直接使用/save 即可 ,
// 如果类上边也有这个注解 , 那么访问路径就是 , /user/save
@RequestMapping(value = "/save",method = RequestMethod.POST) //二级访问
public String save(){
System.out.println("Controller save Running...");
//return 直接就是对应的资源文件
return "success.jsp";
//前边什么都不写,就是相对位置,
//在使用请求路径,/user/save时,进行跳转,会寻找/user/success.jsp
//所以这里要加一个 / , 表示从项目的根路径下找资源
// "/success.jsp";
}
}
spring-mvc组件扫描器的其他用法 :
spring-mvc.xml文件
<!--Controller的组件扫描-->
<context:component-scan base-package="com.sichen">
<!--二者不能重复使用-->
<!--exclude : 表示排除这个之外的内容-->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<!--include : 表示扫描指定的这个内容-->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
spring-mvc配置文件的其他配置 :(了解)
spring-mvc配置文件除了可以配置组件扫描之外 , 还可以配置其他组件
- 这些组件在spring-mvc的jar下的DispatcherServlet.properties文件中可以看到 , 可以指定其中的一些属性 , (比较深层次 , 了解即可)
- 使用的是 和 这些标签完成的功能
可以修改那些带有set方法的参数内容:
各个组件的名称 , 以及功能 :
- DispatcherServlet : 前端控制器
- 需要我们手动配置的 , 帮助我们调用其他的一些功能组件
- HandlerMapping : 处理器映射器
- 帮我们解析请求 , 返回一个处理器执行链
- HandlerAdapter : 处理器配适器
- 被前端处理器调用 , 帮我们去执行对应的处理器
- Handler : 处理器
- 相当于就是 Controller
- View Resolver : 视图解析器
- 帮我们将view解析出来
- View : 视图
- 封装了视图的一些信息
在Spring-MVC的各大组件中 , 处理器映射器 , 处理器配适器 , 视图解析器 , 称为Spring-MVC的三大组件
SpringMVC的数据响应:
你想使用那些对象 , 都可以在方法的参数中 , 添加这个对象 , Spring-MVC内部都可以进行创建 , 并且将其放在域中 , 你在方法中直接使用就可以了
(1)页面跳转
-
直接返回字符串
- 此种方式会将返回的字符串与视图解析器的前后缀进行拼接后跳转
-
通过ModelAndView对象返回
-
@RequestMapping(value = "/save2") public ModelAndView save2(){ /* * Model: 模型 , 作用封装数据 * View : 视图 , 作用展示数据 * */ ModelAndView modelAndView = new ModelAndView(); //设置模型数据 , 在页面中配合el表达式 , 来获取数据 modelAndView.addObject("username","sichen"); //设置视图 : modelAndView.setViewName("/success.jsp"); return modelAndView; }
-
或者直接在参数中添加 , Spring-MVC会根据你的参数 ,自动给你创建一个ModelAndView对象存储到容器中
-
@RequestMapping(value = "/save3") public ModelAndView save3(ModelAndView modelAndView){ //设置模型数据 , 在页面中配合el表达式 , 来获取数据 modelAndView.addObject("username","sichen"); //设置视图 : modelAndView.setViewName("/success.jsp"); return modelAndView; }
-
(2)写回数据
-
直接返回字符串
-
(1)通过Spring-MVC框架注入的response对象 , 使用response.getWriter().print(“hello world”)回写数据, 此时不需要视图跳转 , 业务方法返回值为 void
-
@RequestMapping(value = "/save4") public void save4(HttpServletResponse response) throws IOException { response.getWriter().print("思尘"); }
-
-
(2)如果你想直接返回字符串 , 而不是使用response对象 , 那么就需要使用@ResponseBody注解 , 告诉SpringMVC框架 , 方法返回的字符串不是跳转 , 而是直接在http响应体中返回
-
//使用@ResponseBody //告诉SpringMVC 不进行跳转 , 返回的字符串是直接响应的 @ResponseBody @RequestMapping(value = "/save5") public String save5() throws IOException { return "hello sichen"; }
-
-
-
返回对象或集合
-
//使用json返回数据 , 将数据的转换工作交给springmvc完成 @ResponseBody @RequestMapping("/save7") //期望SpringMVC自动将User转换为json格式的字符串 public User save7() throws JsonProcessingException { User user = new User(); user.setName("思尘"); user.setAge(21); return user; }
这个工作需要你在springmvc.xml文件中配置处理器映射器
<!--配置处理器映射器--> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="messageConverters"> <list> <!--注入jackson转换的转换器--> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/> </list> </property> </bean>
-
简便方式配置处理器映射器 , 是返回数据自动转换为json类型数据
上边配置配置处理器映射器 , 的时候配置是比较繁琐的 , 这里springmvc提供了一个注解驱动代替上边的配置 ,
<mvc:annotation-driven/>
在SpringMVC的各大组件中 , 处理器映射器 , 处理器配适器 , 视图解析器 , 称为SpringMVC的三大组件 ,
使用 <mvc:annotation-driven > 自动加载处理器映射器 ,
处理器适配器 , 可用在Spring-MVC的配置文件中使用 , <mvc:annotation-driven >替代注解处理器和配适器的配置
同时 , 使用mvc:annotation-driven 默认底层就会集成jackson进行对象或集合的json格式字符串的转换
SpringMVC获得请求数据:
(1)获得请求参数 :
客户端请求参数的格式是 : name=value&age=value…
服务器端获得请求的参数 , 有时还需要进行数据的封装 , SpringMVC可以接收如下类型的参数 :
- 基本类型参数
- POJO类型参数 (bean)
- 数组类型的参数
- 集合类型的参数
获得基本类型的参数 :
Controller中的业务方法的参数名称要与请求参数的name一致 , 参数值会自动映射匹配 , 会自动获取请求参数的值
请求 : http://localhost:8080/request/save1?name=思尘&age=21
@RequestMapping("/save1")
@ResponseBody
//请求中的参数名称和方法参数中的name一致时 , springMVC会自动进行赋值
// http://localhost:8080/request/save1?name=思尘&age=21
public User save1(User user,String name,int age){
user.setName(name);
user.setAge(age);
return user;
// {"name":"思尘","age":21}
}
获得POJO类型参数 :
Controller中的业务方法的POJO参数的属性与请求参数的name一致 , 参数值会自动映射匹配 , springMVC会自动对请求参数进行封装
//请求参数中的name名和一个bean对象中的参数一致时 , springMVC会自动进行封装
// http://localhost:8080/request/save2?name=思尘&age=21
@RequestMapping("/save2")
@ResponseBody
public User save2(User user){
return user;
// {"name":"思尘","age":21}
}
获取数组类型的参数:
Controller中的业务方法数组名称与请求参数中的name一致 , 参数值会自动映射匹配
//获取请求参数中重复的值 , 比如说爱好..
// http://localhost:8080/request/save3?strs=思尘&strs=闻熙灏
@RequestMapping("/save3")
@ResponseBody
public List<String> save3(String[] strs){
return Arrays.asList(strs);
// ["思尘","闻熙灏"]
}
获取集合类型参数:
获取集合参数的时候 , 要将集合的参数包装到一个POJO中才可以
//domain : VO
private List<User> userList;
@RequestMapping("/save4")
@ResponseBody
public void save4(VO vo){
System.out.println(vo);
}
from表单 : 使用js :
<from action="${pageContext.request.contextPath}/request/save4" method="post">
<%--表示是第几个User对象的username--%>
<!--这里的name要是domain中的参数名一致 , 那是一个数组 , 所以要增加一个下标 , 表示是第几个User对象 , 并且是什么内容-->
<input type="text" name="userList[0].name"/><br>
<input type="text" name="userList[0].age"/><br>
<input type="text" name="userList[1].name"/><br>
<input type="text" name="userList[1].age"/><br>
<input type="submit" value="提交"/>
</from>
使用ajax请求的方式请求数据 :
<script src="${pageContext.request.contextPath}/js/jquery-3.3.1.js"/>
<script>
var userList = new Array();
userList.push({name: "sichen", age: 18});
userList.push({name:"wenxihao",age:21});
$.ajax({
type:"POST",
url:"${pageContext.request.contextPath}/request/save5",
data:JSON.stringify(userList),
contentType:"application/json;charset=UTF-8",
});
</script>
@RequestMapping("/save5")
@ResponseBody
//这里需要在参数前添加一个注解 @RequestBody
public void save5(@RequestBody List<User> userList){
System.out.println(userList);
}
找不到js文件的解决方式 :
这里是应为在web.xml中注册spring-mvc的前端控制器的时候 , 使用的是缺省的路径格式 , 这会导致在请求数据的时候 , 会将js的文件的名称也当做一个请求路径来请求 , 这样就导致 , 请求不到对应的资源
在springmvc.xml文件中添加 :
<!--开放资源的访问权限-->
<!--
mapping表示映射地址 , 也就是要开放的资源 ,
location表示的是资源所在的位置-->
<mvc:resources mapping="/js/**" location="/js/"/>
<!--或者使用-->
<mvc:default-servlet-handler/>
<!--这个是表示 , 如果请求的资源找不到的话 , 就使用原始的tomcat的内部机制去找这个资源-->
解决请求数据乱码的问题 :
当post请求时 , 数据会出现乱码 , 我们可以设置一个过滤器来进行编码的过滤
web.xml文件中配置
<!--配置全局过滤的filter-->
<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>
参数绑定注解 @RequestParam 参数名称不一致时
当你请求参数名称与Controller的业务方法的参数名称不一致时 , 就需要通过@RequestParam注解显示的绑定
//使用@RequestParam注解来进行 , 请求参数的赋值
@RequestMapping("/save6")
@ResponseBody
//参数值就是请求时使用的参数名称
public void save6(@RequestParam(value = "name") String username){
System.out.println(username);
}
注解中有三个参数可以使用 :
- value : 与请求参数名称一致
- required : 此在指定的请求参数是否必须包括 , 默认是true , 提交时如果没有此参数则报错 ,
- defaultValue : 当没有指定的请求参数时 , 则使用指定的默认值赋值
获取Restful风格的参数 :
Restful : 是一种软件的架构风格 , 设计风格 , 而不是标准 , 只是提供了一组设计原则和约束条件 , 主要用于客户端和服务器交互类的软件, 基于这个设计风格设计的软件可以更简洁 , 更有层次 , 更易于实现缓存机制等 …
Restful风格的请求是使用 “url+请求方式” , 表示一次请求目的的 , HTTP协议里面四个表示操作方式的动词如下 :
- GET : 用于获取资源
- POST : 用于新建资源
- PUT : 用于更新资源
- DELETE : 用于删除资源
例如 :
- /user/1 GET : 表示得到id=1 的user
- /user/1 DELETE : 表示删除id =1 的user
- /user/1 PUT : 表示更新id = 1的user
- /user POST : 表示新增user
使用注解 : @PathVariable : 注意这里边的值 , 必须要和参数名称一致
//使用@PathVariable
@RequestMapping("/save7/{username}")
@ResponseBody
public void save7(@PathVariable(value = "username") String username){
System.out.println(username);
}
自定义类型转换器 :
- SpringMVC默认已经提供了一些常用的类型转换器 , 例如客户端提交的字符串转换成int类型进行参数设置
- 但是不是所有的数据类型都提供了转换器 , 没有提供的就需要自定义转换器 , 例如 : 日期类型的数据就需要自定义转换器
实现步骤 :
(1)定义转换器类实现Converter接口 (springMVC提供的转换器接口)
import org.springframework.core.convert.converter.Converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateConverter implements Converter<String,Date> {
public Date convert(String dateStr){
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date date = null;
try {
date = format.parse(dateStr);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}
(2)在配置文件中声明转换器
<!--声明自定义转换器-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.sichen.converter.DateConverter"/>
</list>
</property>
</bean>
(3)在 中引用转换器
<!--mvc的注解驱动-->
<mvc:annotation-driven conversion-service="conversionService"/>
获取Servlet相关的API:
常见的对象有
- HttpServletRequest
- HttpServletResponse
- HttpSession
直接在业务方法的参数的位置写入即可 , SpringMVC会自动帮你创建这个对象
获取请求头的数据 :
(1)使用注解 @RequestHeader获取请求头信息
可以获取请求头信息 , 相当于web阶段学习的Request.getHeader(name)
@RequestHeader注解的属性如下
- value : 请求头的名称
- required : 是否必须携带此请求头
//使用@RequestHeader注解获取请求头
@RequestMapping("/save9")
@ResponseBody
public void save9(@RequestHeader(value = "User-Agent" ,required = false) String user_agent){
System.out.println(user_agent);
}
常用来对Cookie来进行操作
(2)直接获取Cookie的值 :
使用@CookieValue注解 : 可以直接获取指定Cookie的值
- value : 指定cookie的名称
- required : 是否必须携带次cookie
文件上传 :
文件上传客户端三要素:
- 表单项type = “file”
- 表单的提交方式是post
- 表单的enctype属性是多部分的表单形式 ,
- 即enctype=“multipart/form-data”
<form action="${pageContext.request.contextPath}/request/save10" method="post" enctype="multipart/form-data">
名称 : <input type="text" name="username"><br>
文件 : <input type="file" name="upload"><br>
<input type="submit" value="提交">
</form>
- 当form表单修改为多部分表单的时候 , request.getParameter()将失效
- enctype = "application/x-www-form-urlencoded"是 , form表单的正文内容格式是 : key=value&key=value&key=value
- 当form表单的enctype取值为Mutilpart/from-data时 , 请求正文内容就变成多部分格式
单文件上传实现
(1)导入fileupload和io坐标
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
(2)配置文件上传解析器
<!--指定文件上传解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--上传文件总大小-->
<property name="maxUploadSize" value="5242800"/>
<!--上传单个文件的大小-->
<property name="maxUploadSizePerFile" value="5242800"/>
<!--上传文件的编码格式-->
<property name="defaultEncoding" value="UTF-8"/>
</bean>
(3)编写文件上传代码
@RequestMapping("/save10")
@ResponseBody
//这里的MultipartFile upload 参数名要和表单对应文件选项的name值一致
public void save10(String username, MultipartFile upload) throws IOException {
System.out.println(username);
System.out.println(upload);
//获得上传文件的名称 :
String filename = upload.getOriginalFilename();
//使用自带的方法将文件保存在指定的目录中
upload.transferTo(new File("D:\\riji\\wenjian\\"+filename));
}
多文件上传实现 :
- (1)将上边的表单项重复多个 , 修改每个对应的name值 , 在文件上传代码的时候 , 设置对应个数的MultipartFile upload 参数 , 注意参数的名字一一对应 , 即可
- (2)也可以将name的值设置一样 , 在java代码中使用数组的形式 , 接收数据 , 然后使用for循环来遍历数组 , 完成文件的保存
@RequestMapping("/save12")
@ResponseBody
//使用数组的形式 , 来获取保存文件
public void save12(MultipartFile[] upload1) throws IOException {
for (MultipartFile multipartFile : upload1) {
String filename = multipartFile.getOriginalFilename();
multipartFile.transferTo(new File("D:\\riji\\wenjian\\"+filename));
}
}
SpringMVC拦截器 (interceptor):
概述:
SpringMVC的拦截器类似于Servlet开发中的过滤器Filter , 用于对处理器进行预处理和后处理
将拦截器按一定的顺序联结成一条链 , 这条链称为拦截器链(interceptor Chain) ,
在访问被拦截的方法或字段时 , 拦截器链中的拦截器就会按照之前定义的顺序被调用 , 拦截器也是AOP思想的具体实现
Spring-MVC拦截器可以设置标签排除不需要拦截的资源
快速入门:
自定义拦截器很简单 , 只有如下两步 :
(1)创建拦截器类 , 实现HandlerInterceptor接口
public class MyInterceptor implements HandlerInterceptor {
@Override
//在目标方法执行之前执行的
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle...");
//这里输出的是false , 就会阻止继续访问
//输出true的话 , 放行
return true;
}
@Override
//在目标方法执行之后 , 视图返回之前执行的
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle...");
}
@Override
//在整个流程都执行完毕后 , 执行
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion...");
}
}
(2)配置拦截器 : 在spring-mvc中进行配置 :
<!--配置拦截器-->
<mvc:interceptors><!--这里可以创建多个拦截器-->
<mvc:interceptor>
<!--mvc:mapping是指定对那些资源进行拦截 ,
/** 代表对所有资源都进行拦截-->
<mvc:mapping path="/**"/>
<bean class="com.sichen.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
实现用户登录权限的检测 :
@Override
//在目标方法执行之前执行的
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle...");
//这里输出的是false , 就会阻止继续访问
//输出true的话 , 不会阻拦
String name = request.getParameter("name");
if ("yes".equals(name)){
return true;
}else{
request.getRequestDispatcher("/error.jsp").forward(request,response);
return false;
}
}
interceptor拦截器链的执行顺序 :
//和filter的执行顺序是一样的 , 在配置文件中 , 写在前边的先执行下边的方法 ,
@Override
//在目标方法执行之前执行的
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return false;
}
//但是后两个方法 , 的顺序是反过来的 , 类似于进栈的操作 , 在第一个方法的时候 , 这些拦截器先存入堆栈中 , 在后续方法的执行过程中 , 会优先执行堆栈上边
SpringMVC的异常处理机制:
过去我们直接是在业务层 (也就是Service层进行的异常抛出处理 ,)但是 , 这样会导致代码过度的耦合 , 可读性差 , 代码不容易维护 , 等等缺点
异常处理的思路:
系统中的异常包括两类 , 预期异常和运行时异常 RuntimeException
前者通过捕获异常从而获取异常信息 ,
后者主要通过规范代码的开发 , 测试等手段 , 减少运行时异常的发生
系统的Dao , Service , Controller 出现都通过throws Exception向上抛出 , 最后由SpringMVC前端控制器交由异常处理器进行异常处理 ,
HandlerExceptionResolver : 异常处理器
异常处理的两种方式 :
(1)使用SpringMVC提供的简单异常处理器 : SimpleMappingExceptionResolver
SpringMVC已经定义好了该类型转换器 , 在使用时可以根据项目情况进行响应异常与视图的映射配置
<!--配置简单的异常处理器-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!--这个是指定默认的异常 , 及跳转路径-->
<property name="defaultErrorView" value="error"/>
<property name="exceptionMappings">
<map>
<!--这里的key值是异常的全限定名称 , value的值就是发生异常时的跳转路径-->
<entry key="java.lang.ClassCastException" value="error"/>
<!--可以指定多个异常-->
<entry key="java.io.FileNotFoundException" value="error1"/>
</map>
</property>
</bean>
(2)使用Spring的异常处理接口 : HandlerExceptionResolver
① : 创建异常处理器类实现 HandlerExceptionResolver
/**
* @param o Object
* @param e Exception : 参数Exception : 异常对象
* @return 返回值 , ModelAndView , 跳转到错误视图信息
*/
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
ModelAndView modelAndView = new ModelAndView();
if (e instanceof MyException){
//判断e , 是不是MyException的实例
modelAndView.addObject("info","自定义异常");
}else if (e instanceof ClassCastException){
modelAndView.addObject("info","类转换异常");
}
modelAndView.setViewName("error");
return modelAndView;
}
② : 配置异常处理器
<!--这里就比较简单了 , 只需要将类加载进内存即可-->
<!--自定义异常处理器-->
<bean class="com.itheima.resolver.MyExceptionResolver"/>
③ : 编写异常页面
④ : 测试异常跳转
在配置了这些之后 , 再有异常就直接往上层抛即可 , 我们配置了一个异常的处理类 , 会帮助我们处理这些异常
* @param o Object
* @param e Exception : 参数Exception : 异常对象
* @return 返回值 , ModelAndView , 跳转到错误视图信息
*/
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
ModelAndView modelAndView = new ModelAndView();
if (e instanceof MyException){
//判断e , 是不是MyException的实例
modelAndView.addObject("info","自定义异常");
}else if (e instanceof ClassCastException){
modelAndView.addObject("info","类转换异常");
}
modelAndView.setViewName("error");
return modelAndView;
}
② : 配置异常处理器
```xml
<!--这里就比较简单了 , 只需要将类加载进内存即可-->
<!--自定义异常处理器-->
<bean class="com.itheima.resolver.MyExceptionResolver"/>
③ : 编写异常页面
④ : 测试异常跳转
在配置了这些之后 , 再有异常就直接往上层抛即可 , 我们配置了一个异常的处理类 , 会帮助我们处理这些异常