Java全局异常处理解决方案
背景:
在项目开发中,习惯去设计一些自定义的异常类来处理各层的异常。比如:
- DAO层会有对应的DAOException.java
- Service层有对应的ServiceException.java
- Controller层有对应的ControllerException.java
当程序遇到不可忽视的错误时,会直接throw出这些异常,这就意味着需要一种全局异常处理机制来对这些异常进行统一管理(比如:返回给用户一个错误页面)
本文仅介绍了两种统一处理异常的方式:基于servlet的过滤器和基于Spring的@ExceptionHandler方式
未处理服务器异常:
处理异常后:
自定义异常类:
- BaseException.java——所有自定义异常的父类
package com.nys.exceptions;
import com.nys.enums.ResultEnum;
/**
* 基础异常类
* @author nysheng
*/
public class BaseException extends RuntimeException {
private Integer code=0;
public BaseException(String msg) {
super(msg);
}
public BaseException(Integer code,String msg){
super(msg);
this.code=code;
}
public BaseException(ResultEnum resultEnum){
super(resultEnum.getMsg());
this.code=resultEnum.getCode();
}
public Integer getCode(){
return code;
}
}
- DAOException.java——具体异常类
package com.nys.exceptions;
import com.nys.enums.ResultEnum;
/**
* DAO层异常统一
* @author nysheng
*/
public class DAOException extends BaseException {
public DAOException(String msg) {
super(msg);
}
public DAOException(Integer code,String msg){
super(code,msg);
}
public DAOException(ResultEnum resultEnum){
super(resultEnum.getCode(),resultEnum.getMsg());
}
}
一、过滤器实现全局异常处理
这里采用的是注解@WebFilter方式添加的过滤器,并以Slf4j+Logback的方式进行日志记录。
package com.nys.filter;
import com.nys.bean.ApplicationConfig;
import com.nys.exceptions.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletException;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 全局异常拦截处理
* @author nysheng
*/
@WebFilter("/*")
public class ExceptionFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse resp=(HttpServletResponse)servletResponse;
HttpServletRequest req=(HttpServletRequest) servletRequest;
try{
filterChain.doFilter(req, resp);
}catch (RuntimeException e){
Logger logger = LoggerFactory.getLogger(ExceptionFilter.class);
//判断是否为自定义异常
Integer errorCode=0;
if(e instanceof DAOException){
//DAO层异常
errorCode=1000;
}else if(e instanceof ServiceException){
//业务层异常
errorCode=2000;
}else if(e instanceof ControllerException){
//控制层异常
errorCode=3000;
}
logger.error("服务器出现异常,错误码:{},错误信息:{}",errorCode,e.getMessage());
resp.sendRedirect(ApplicationConfig.REMOTE_REQUEST_ADDR+"/html/fail.html");
}
}
@Override
public void destroy() {}
}
二、Spring异常处理方式Handler
@ControllerAdvice+@ExceptionHandler,同样以Slf4j+Logback记录日志
package com.nys.exceptionshandler;
import com.nys.bean.ApplicationConfig;
import com.nys.exceptions.BaseException;
import com.nys.exceptions.DAOException;
import com.nys.exceptions.ServiceException;
import com.nys.exceptions.ServletException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
/**
* 全局异常处理
* @author nysheng
*/
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler({DAOException.class,ServiceException.class, ServletException.class})
public ModelAndView serviceExceptionHandler(BaseException e){
Logger logger=LoggerFactory.getLogger(GlobalExceptionHandler.class);
logger.error("服务器出现异常,错误码:{},错误信息:{}",e.getCode(),e.getMessage());
return new ModelAndView("redirect:".concat(ApplicationConfig.REMOTE_REQUEST_ADDR).concat("/html/fail.html"));
}
}
测试Controller:
@GetMapping("/test")
public void test(){
throw new DAOException(1,"Dao异常");
}
        我曾七次鄙视自己的灵魂:
  第一次,当它本可进取时,却故作谦卑;
  第二次,当它在空虚时,用爱欲来填充;
  第三次,在困难和容易之间,它选择了容易;
  第四次,它犯了错,却借由别人也会犯错来宽慰自己;
  第五次,它自由软弱,却把它认为是生命的坚韧;
  第六次,当它鄙夷一张丑恶的嘴脸时,却不知那正是自己面具中的一副;
  第七次,它侧身于生活的污泥中,虽不甘心,却又畏首畏尾。
时间仓促,如有错误欢迎指出,欢迎在评论区讨论,如对您有帮助还请点个推荐、关注支持一下
作者:博客园 - 角刀牛
出处:https://www.cnblogs.com/jiaodaoniujava/
该文章来源互联网,本博仅以学习为目的,版权归原作者所有。
若内容有侵犯您权益的地方,请公告栏处联系本人,本人定积极配合处理解决。