SpringMVC 自定义异常处理器示例

2022-01-06 0 By admin

在SpringMVC项目中,使用使用 HandlerExceptionResolver 实现全局异常处理器。当抛出异常后,使用相应的符合用户体验的友好界面显示异常。

一、创建自定义异常类

设置自定义异常类,名称为OperationException。
注意:
该自定义异常类继承的是RuntimeException类。

  1. 因为一般项目的Service层逻辑都会使用Spring提供的事务管理,当Service层需要抛出自定义异常时,如果该自定义异常继承的是Exception类,则Spring提供的事务管理将会失效。
  2. 所以这里的自定义异常类继承的是RuntimeException类,这样才不会使Spring提供的事务管理失效。

Spring管理的事务,无论是声明式事务还是注解式事务,默认是在抛出运行异常(RuntimeException异常)时,才会被Spring框架捕获到然后回滚。

package com.pjb.fms.exception;
public class OperationException extends RuntimeException {
    private String errorMessage; //异常信息
    public OperationException(String errorMessage) {
        super(errorMessage);
        this.errorMessage = errorMessage;
    }
    public String getErrorMessage(){
        return errorMessage;
    }
    public void setErrorMessage(String errorMessage){
        this.errorMessage = errorMessage;
    }
}

二、创建全局异常处理器

创建全局异常处理器 OperationExceptionResolver类,该类继承HandlerExceptionResolver接口,并且实现resolveException方法。

package com.pjb.fms.exception;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class OperationExceptionResolver implements HandlerExceptionResolver {
    //日志对象
    private Logger logger = LogManager.getLogger(OperationExceptionResolver.class);
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        //1、解析出异常类型
        OperationException operationException = null;
        if(ex instanceof OperationException) {
            //2、如果该异常类型是自定义的操作异常,直接获取异常信息,在错误页面展示
            operationException = (OperationException)ex;
        } else {
            //3、如果该异常类型不是自定义的操作异常,构建一个自定义的操作异常类型
            operationException = new OperationException("系统错误,请联系管理员");
        }
 
        //错误信息
        String errorMessage = operationException.getErrorMessage();
        //记录异常日志
        logger.error(errorMessage);
        //返回错误页面
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("errorMessage",errorMessage);
        modelAndView.setViewName("/error.jsp");
        return modelAndView;
    }
}

三、创建名称为error.jsp的页面

优化用户体验的友好界面,用于显示异常信息。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>操作失败</title>
    <meta name="author" content="pan_junbiao的博客">
</head>
<body>
<div align="center">
    <h1>操作失败</h1>
    <span style="color: red;">
        <%=request.getAttribute("errorMessage") == null ? "" : "失败原因:" + request.getAttribute("errorMessage")%>
    </span>
</div>
</body>
</html>

四、使用配置文件的方式注册

然后在SpringMVC核心配置文件springmvc.xml中将定义的全局异常处理器配置进去:

<!-- 全局异常处理器 -->
<bean class="com.pjb.fms.exception.OperationExceptionResolver"></bean>

五、测试

创建测试的Controller控制器方法,该方法抛出一个自定义异常。

@RequestMapping(value = "login", method = RequestMethod.POST)
public ModelAndView login() throws Exception {
    throw new OperationException("账号或密码错误");
}