【SpringMVC】 4.2 异常处理
SpringMVC学习记录
注意:以下内容是学习 北京动力节点 的SpringMVC视频后所记录的笔记、源码以及个人的理解等,记录下来仅供学习
第4章 SpringMVC 核心技术
4.2异常处理
?SpringMVC框架处理异常的常用方式:使用@ExceptionHandler注解处理异常。
异常处理步骤:
- 新建maven web项目
- 加入依赖
- 新建一个自定义异常类 MyUserException , 再定义它的子类NameException ,AgeException
- 在controller抛出NameException , AgeException
- 创建一个普通类,作用全局异常处理类
(1). 在类的上面加入@ControllerAdvice
(2). 在类中定义方法,方法的上面加入@ExceptionHandler - 创建处理异常的视图页面
- .创建springmvc的配置文件
(1).组件扫描器 ,扫描@Controller注解
(2).组件扫描器,扫描@ControllerAdvice所在的包名
(3).声明注解驱动
项目结构:
4.2.1 @ExceptionHandler 注解
?使用注解@ExceptionHandler可以将一个方法指定为异常处理方法。该注解只有一个可 选属性value,为一个Class<?>数组,用于指定该注解的方法所要处理的异常类,即所要匹 配的异常。
?而被注解的方法,其返回值可以是ModelAndView、String,或void,方法名随意,方法 参数可以是 Exception 及其子类对象、HttpServletRequest、HttpServletResponse 等。系统会 自动为这些方法参数赋值。
对于异常处理注解的用法,也可以直接将异常处理方法注解于Controller之中。
(1) 自定义异常类
?定义三个异常类:NameException、AgeException、MyUserException。其中 MyUserException 是另外两个异常的父类。
MyUserException.java
package com.bjpowernode.exception;
public class MyUserException extends Exception {
public MyUserException() {
super();
}
public MyUserException(String message) {
super(message);
}
}
AgeException.java
package com.bjpowernode.exception;
//当年龄有问题时,抛出的异常
public class AgeException extends MyUserException {
public AgeException() {
super();
}
public AgeException(String message) {
super(message);
}
}
NameException.java
package com.bjpowernode.exception;
//表示当用户的姓名有异常,抛出NameException
public class NameException extends MyUserException {
public NameException() {
super();
}
public NameException(String message) {
super(message);
}
}
(2) 修改 Controller 抛出异常
MyController.java
package com.bjpowernode.controller;
import com.bjpowernode.exception.AgeException;
import com.bjpowernode.exception.MyUserException;
import com.bjpowernode.exception.NameException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.ws.RequestWrapper;
/**
* @RequestMapping:
* value : 所有请求地址的公共部分,叫做模块名称
* 位置: 放在类的上面
*/
@Controller
public class MyController {
@RequestMapping(value = "/some.do")
public ModelAndView doSome(String name,Integer age) throws MyUserException {
//处理some.do请求了。 相当于service调用处理完成了。
ModelAndView mv = new ModelAndView();
//try {
//根据请求参数抛出异常
if (!"zs".equals(name)) {
throw new NameException("姓名不正确!!!");
}
if (age == null || age > 80) {
throw new AgeException("年龄比较大!!!");
}
//}catch(Exception e){
// e.printStackTrace();
//}
mv.addObject("myname",name);
mv.addObject("myage",age);
mv.setViewName("show");
return mv;
}
}
(3) 定义异常请求以及响应页面
请求页面:
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String basePath = request.getScheme() + "://" +
request.getServerName() + ":" + request.getServerPort() +
request.getContextPath() + "/";
%>
Title
处理异常的,全局异常处理
响应页面
ageError.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
ageError.jsp
提示信息:${msg}
系统异常消息:${ex.message}
defaultError.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
defaultError.jsp
提示信息:${msg}
系统异常消息:${ex.message}
nameError.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
nameError.jsp
提示信息:${msg}
系统异常消息:${ex.message}
(4) 定义全局异常处理类
不过,一般不这样使用。而是将异常处理方法专门定义在一个类中,作为全局的异常处理类。需要使用注解@ControllerAdvice,字面理解就是“控制器增强”,是给控制器对象增强功能的。使用@ControllerAdvice 修饰的类中可以使用@ExceptionHandler。当使用@RequestMapping 注解修饰的方法抛出异常时,会执行@ControllerAdvice 修饰的类中的异常处理方法。@ControllerAdvice 是使用@Component 注解修饰的,可以context:component-scan扫描到@ControllerAdvice 所在的类路径(包名),创建对象。
GlobalExceptionHandler.java
package com.bjpowernode.handler;
import com.bjpowernode.exception.AgeException;
import com.bjpowernode.exception.NameException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
/**
* @ControllerAdvice : 控制器增强(也就是说给控制器类增加功能--异常处理功能)
* 位置:在类的上面。
* 特点:必须让框架知道这个注解所在的包名,需要在springmvc配置文件声明组件扫描器。
* 指定@ControllerAdvice所在的包名
*/
@ControllerAdvice
public class GlobalExceptionHandler {
//定义方法,处理发生的异常
/*
处理异常的方法和控制器方法的定义一样, 可以有多个参数,可以有ModelAndView,
String, void,对象类型的返回值
形参:Exception,表示Controller中抛出的异常对象。
通过形参可以获取发生的异常信息。
@ExceptionHandler(异常的class):表示异常的类型,当发生此类型异常时,
由当前方法处理
*/
@ExceptionHandler(value = NameException.class)
public ModelAndView doNameException(Exception exception){
//处理NameException的异常。
/*
异常发生处理逻辑:
1.需要把异常记录下来, 记录到数据库,日志文件。
记录日志发生的时间,哪个方法发生的,异常错误内容。
2.发送通知,把异常的信息通过邮件,短信,微信发送给相关人员。
3.给用户友好的提示。
*/
ModelAndView mv = new ModelAndView();
mv.addObject("msg","姓名必须是zs,其它用户不能访问");
mv.addObject("ex",exception);
mv.setViewName("nameError");
return mv;
}
//处理AgeException
@ExceptionHandler(value = AgeException.class)
public ModelAndView doAgeException(Exception exception){
//处理AgeException的异常。
/*
异常发生处理逻辑:
1.需要把异常记录下来, 记录到数据库,日志文件。
记录日志发生的时间,哪个方法发生的,异常错误内容。
2.发送通知,把异常的信息通过邮件,短信,微信发送给相关人员。
3.给用户友好的提示。
*/
ModelAndView mv = new ModelAndView();
mv.addObject("msg","你的年龄不能大于80");
mv.addObject("ex",exception);
mv.setViewName("ageError");
return mv;
}
//处理其它异常, NameException, AgeException以外,不知类型的异常
@ExceptionHandler
public ModelAndView doOtherException(Exception exception){
//处理其它异常
ModelAndView mv = new ModelAndView();
mv.addObject("msg","你的年龄不能大于80");
mv.addObject("ex",exception);
mv.setViewName("defaultError");
return mv;
}
}
@ControllerAdvice 是使用@Component 注解修饰的
这句话看了源码是这样的,ControllerAdvice类是用@Component 注解的,
??@Component 作用:把普通pojo类实例化到spring容器中,相当于配置文件中的
??@Component,@Service,@Controller,@Repository注解的类,并把这些类纳入进spring容器中管理。
(5) 定义 Spring 配置文件
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
myweb
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
1
myweb
*.do