springmvc自定义全局异常处理

springmvc全局异常

  • 实现步骤
  • 在web层下新建一个类
    • 通过实现spring的HandlerExceptionResolver接口来捕获所有的异常。
    • 写一个异常处理类实现HandlerExceptionResolver接口
  • 如下:

    public class MvcWholeExceptionResolver implements HandlerExceptionResolver
    {
    private static final Logger logger = Logger.getLogger(MvcWholeExceptionResolver.class);
    //mvc捕获异常
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,Exception exception)
    {
    //可以在mv里放异常的页面地址和异常的信息
    ModelAndView mv=new ModelAndView();
    if(exception!=null)
    {
    //自定义封装的业务异常抛出类
    BizException bizException = null;
    logger.warn("MVC全局异常捕捉类捕捉到异常");
    if(exception instanceof LoginException)
    {
    logger.warn("捕捉到业务异常子类登录异常抛出类:LoginException");
    bizException=(BizException)exception;

              }else{
                  logger.warn("捕捉到系统未知异常:UNCLASSFY_EXCEPTION");
                  logger.warn("UNCLASSFY_EXCEPTION:   "+exception);
                  bizException=BizException.UNCLASSFY_EXCEPTION;
                  //要捕捉更多业务类的异常,在自定义更多像LoginException的子类即可,或者在建立像BizException一样的类,这里就举这两个例子,其它仿照拓展
    
              }
              logger.warn("异常代码:"+bizException.getCode()+"   异常信息:"+bizException.getMessage());
              //如果前端是通过ajax请求的后台抛出异常,那么无需返回异常页面,只需要返回异常信息,方法如下:
              //在request作用域里保存异常的代码和信息
              request.setAttribute(UsualConstants.RETURN_ERROR_CODE_KEY, bizException.getCode());
              request.setAttribute(UsualConstants.RETURN_ERROR_MSG_KEY, bizException.getMessage());
              //在通过转发到controller里的方法,返回@ResponsBody方式,前台ajax里自然会捕捉到,如下:
              try{
                  logger.warn("转发到ajax的统一异常处理方法");
                  request.getRequestDispatcher("/manage/login/jsonException").forward(request, response);
    
              }catch(Exception e){
                  logger.warn("转发到ajax统一异常处理出错");
                  e.printStackTrace();
              }
          }
          //虽然ajax的异常在前面已经返回给前端了,但是还会执行到这里,如果在mv里没有加任何东西或者只加异常信息,return时会报错,但不影响前端,前端已经捕捉到ajax的异常了
          //如果在mv里有加入跳转的异常页面,那么前端也会跳转,根据具体需要要不要跳转具体异常页面,这里不放具体页面
          mv.addObject(UsualConstants.RETURN_ERROR_MSG_KEY,bizException.getMessage());
          return mv;
      }
    }
    • 在springMVC的配置文件中要指定全局异常处理类的位置,如下:

    • ajax的统一异常处理方法,如下:

      @RequestMapping("jsonException")
      @ResponseBody
      public ResultJson jsonException(HttpServletRequest request,Map map)
      {
      logger.warn("统一异常处理方法,取出异常代码和异常信息封装到ResultJson,方法通过@ResponseBody方式返回ResultJson,前台得到信息为json格式");
      Integer errorCode=(Integer)request.getAttribute(UsualConstants.RETURN_ERROR_CODE_KEY);
      String errorMsg=(String)request.getAttribute(UsualConstants.RETURN_ERROR_MSG_KEY);
      ResultJson rj=new ResultJson();
      rj.setKey(errorCode);
      rj.setMessage(errorMsg);
      logger.warn("返回的ResultJson对象为:"+rj);
      return rj;
      }
  • 在service层或者dao层里,自定义统一业务异常抛出类,如下:

    package cn.hj.yzp_app1.common.tools.exception;
    import cn.hj.yzp_app1.common.tools.constantsTools.StatusConstants;
    //业务异常基类,所有业务异常都必须继承于此异常
    public class BizException extends RuntimeExceptionAware
    {
    //RuntimeExceptionAware是自定义的运行时异常类,下面例子会贴出代码
    private static final long serialVersionUID = -697081422076812812L;
    //定义系统未知异常
    public static final BizException UNCLASSFY_EXCEPTION = new BizException(StatusConstants.UNCLASSFY_EXCEPTION_CODE, StatusConstants.UNCLASSFY_EXCEPTION_MSG);

      //异常编号
      protected int code;
      //异常信息
      protected String msg;
    
      //实例化异常
      public BizException newInstance(String message, Object... args) {
          return new BizException(this.code, message, args);
      }
    
      public BizException(int code, String message, Object... args) 
      {
          //父级变量
          super(message);
          this.code = code;
          this.msg = String.format(message, args);
      }
    
      public BizException(String message, Throwable cause) {
          super(message, cause);
      // TODO Auto-generated constructor stub
      }
      public BizException(String message) {
          super(message);
      // TODO Auto-generated constructor stub
      }
      public BizException(Throwable cause) {
          super(cause);
      // TODO Auto-generated constructor stub
      }
      public BizException() {
          super();
      // TODO Auto-generated constructor stub
      }
      /**
      * @return the code
      */
      public int getCode() {
          return code;
      }
      /**
       * @param code the code to set
      */
      public void setCode(int code) {
          this.code = code;
      }
      /**
      * @return the msg
      */
      public String getMsg() {
          return msg;
      }
      /**
      * @param msg the msg to set
      */
      public void setMsg(String msg) {
          this.msg = msg;
      }
      /**
      * @return the serialversionuid
      */
      public static long getSerialversionuid() {
          return serialVersionUID;
      }
    }
  • 运行时异常处理类

    package cn.hj.yzp_app1.common.tools.exception;
    public class RuntimeExceptionAware extends RuntimeException{
    //RuntimeException是系统的运行时异常类
    private static final long serialVersionUID = -4896922247366620859L;

      public RuntimeExceptionAware() {
          super();
      // TODO Auto-generated constructor stub
      }
    
      public RuntimeExceptionAware(String message, Throwable cause) {
          super(message, cause);
          // TODO Auto-generated constructor stub
      }
    
      public RuntimeExceptionAware(String message) {
          super(message);
          // TODO Auto-generated constructor stub
      }
    
      public RuntimeExceptionAware(Throwable cause) {
          super(cause);
          // TODO Auto-generated constructor stub
      }
    }
  • 自定义的登录异常抛出类:LoginException,如下:

    package cn.hj.yzp_app1.common.tools.exception;
    import org.apache.log4j.Logger;
    import cn.hj.yzp_app1.common.tools.exception.BizException;
    //自定义登录异常
    public class LoginException extends BizException{
    //属于业务异常BizException的子类
    private static final long serialVersionUID = -6160637178050783184L;
    private static final Logger logger = Logger.getLogger(LoginException.class);
    public LoginException() {
    super();
    // TODO Auto-generated constructor stub
    }

      public LoginException(int code, String message, Object... args) {
          super(code, message, args);
      // TODO Auto-generated constructor stub
      }
    
      public LoginException(String message, Throwable cause) {
          super(message, cause);
          // TODO Auto-generated constructor stub
      }
    
      public LoginException(String message) {
          super(message);
          // TODO Auto-generated constructor stub
      }
    
      public LoginException(Throwable cause) {
          super(cause);
          // TODO Auto-generated constructor stub
      }
    }
  • 抛出异常例子,如下:

    @RequestMapping("loginVerify")
    @ResponseBody
    public ResultJson loginVerify(UserExtend user,HttpSession session) {
    ResultJson rj=new ResultJson();
    try{
    userServiceImpl.login(user);
    }catch(NullPointerException e){
    //如登录操作时,捕获到空指针异常了,就可以认为是登录异常,抛出后在MvcWholeExceptionResolver里就可以捕捉到,然后在返回前端提示给用户
    throw new LoginException(StatusConstants.NO_LOGINMSG_CODE,StatusConstants.NO_LOGINMSG_MSG);
    }
    }

猜你喜欢

转载自www.cnblogs.com/yao-zhen-peng/p/9815924.html