
代码:
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component//将这句话注释掉,这个异常处理器就不能使用了
public class ExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) {
System.out.println("my exception is running ...."+ex);
ModelAndView modelAndView = new ModelAndView();
if( ex instanceof NullPointerException){
modelAndView.addObject("msg","空指针异常");
}else if ( ex instanceof ArithmeticException){
modelAndView.addObject("msg","算数运算异常");
}else{
modelAndView.addObject("msg","未知的异常");
}
modelAndView.setViewName("error.jsp");
return modelAndView;
}
}
注解实现异常处理
代码:
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@Component
//使用注解开发异常处理器
//声明该类是一个Controller的通知类,声明后该类就会被加载成异常处理器
@ControllerAdvice//如果将这句话注释掉,这个异常处理器就不能使用了
public class ExceptionAdvice {
//类中定义的方法携带@ExceptionHandler注解的会被作为异常处理器,后面添加实际处理的异常类型
@ExceptionHandler(NullPointerException.class)//处理空指针异常
@ResponseBody//如果不写ResponseBody,它就会去找return的页面,添加过后便不会解析成页面
public String doNullException(Exception ex){
return "空指针异常";
}
@ExceptionHandler(ArithmeticException.class)//处理算术异常
@ResponseBody
public String doArithmeticException(Exception ex){
return "ArithmeticException";
}
@ExceptionHandler(Exception.class)//处理全部的异常
@ResponseBody
public String doException(Exception ex){
return "all";
}
}
注解处理器可以拦截到入参类型转换异常:简单来说就是处理的时间比较早,是在参数转换到controller里面之前加载
非注解处理器无法拦截到入参类型转换异常:这个是在后面加载,二者工作时机不同,这个比较晚
项目异常处理方案(理解) 异常分类业务异常:用户这么做的
系统异常:
其他异常:
业务异常:
系统异常:
其他异常:
测试代码
自定义异常类
BusinessException.java
//自定义异常继承RuntimeException,覆盖父类所有的构造方法
public class BusinessException extends RuntimeException {
public BusinessException() {
}
public BusinessException(String message) {
super(message);
}
public BusinessException(String message, Throwable cause) {
super(message, cause);
}
public BusinessException(Throwable cause) {
super(cause);
}
public BusinessException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
SystemException.java系统异常
//自定义异常继承RuntimeException,覆盖父类所有的构造方法
public class SystemException extends RuntimeException {
public SystemException() {
}
public SystemException(String message) {
super(message);
}
public SystemException(String message, Throwable cause) {
super(message, cause);
}
public SystemException(Throwable cause) {
super(cause);
}
public SystemException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
ajax异步请求
<%@page pageEncoding="UTF-8" language="java" contentType="text/html;UTF-8" %> 访问springmvc后台controller,传递Json格式POJO
error.jsp出错跳转的页面
<%--异常消息展示页面--%>
<%@page pageEncoding="UTF-8" language="java" contentType="text/html;UTF-8" %>
${msg}
UserController.java
import com.itheima.domain.User;
import com.itheima.exception.BusinessException;
import com.itheima.exception.SystemException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.ArrayList;
import java.util.List;
@Controller
public class UserController {
@RequestMapping("/save")
@ResponseBody
public List save(@RequestBody User user) {
System.out.println("user controller save is running ...");
//模拟业务层发起调用产生了异常
// int i = 1/0;
// String str = null;
// str.length();
//对用户的非法操作进行判定,并包装成异常对象进行处理,便于统一管理
if(user.getName().trim().length() < 8){
throw new BusinessException("对不起,用户名长度不满足要求,请重新输入!");
}
if(user.getAge() < 0){
throw new BusinessException("对不起,年龄必须是0到100之间的数字!");
}
if(user.getAge() > 100){
throw new SystemException("服务器连接失败,请尽快检查处理!");
}
User u1 = new User();
u1.setName("Tom");
u1.setAge(3);
User u2 = new User();
u2.setName("Jerry");
u2.setAge(5);
ArrayList al = new ArrayList();
al.add(u1);
al.add(u2);
return al;
}
}
异常处理器ProjectExceptionAdvice.java
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@Component
@ControllerAdvice
public class ProjectExceptionAdvice {
@ExceptionHandler(BusinessException.class)
public String doBusinessException(Exception ex, Model m){
//使用参数Model将要保存的数据传递到页面上,功能等同于ModelAndView
//业务异常出现的消息要发送给用户查看
m.addAttribute("msg",ex.getMessage());
return "error.jsp";
}
@ExceptionHandler(SystemException.class)
public String doSystemException(Exception ex, Model m){
//系统异常出现的消息不要发送给用户查看,发送统一的信息给用户看
m.addAttribute("msg","服务器出现问题,请联系管理员!");
//实际的问题现象应该传递给redis服务器,运维人员通过后台系统查看
//实际的问题显现更应该传递给redis服务器,运维人员通过后台系统查看
return "error.jsp";
}
@ExceptionHandler(Exception.class)
public String doException(Exception ex, Model m){
m.addAttribute("msg",ex.getMessage());
//将ex对象保存起来
return "error.jsp";
}
}