zoukankan      html  css  js  c++  java
  • Spring MVC的Controller统一异常处理:HandlerExceptionResolver

    第一步编写实现类

    package
    bdc.base; import java.io.IOException; import java.sql.SQLException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.dao.DataAccessException; import org.springframework.transaction.TransactionException; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; import bdc.common.SimpleJSONResult; import bdc.exception.ArgumentRuntimeException; import bdc.exception.BusinessRuntimeException; import com.fasterxml.jackson.databind.ObjectMapper; /** * 全局异常处理器 * * @author gx * */ public class ExceptionResolver implements HandlerExceptionResolver { private static final Logger logger = LoggerFactory .getLogger(ExceptionResolver.class); @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) { Class<?> clazz = exception.getClass(); StringBuilder builder = new StringBuilder(); if (exception instanceof ArgumentRuntimeException) { builder.append("处理时参数错误:"); } else if (exception instanceof BusinessRuntimeException) { builder.append("业务处理错误:"); } else if (SQLException.class.isAssignableFrom(clazz) || DataAccessException.class.isAssignableFrom(clazz) || TransactionException.class.isAssignableFrom(clazz)) { // 违反主键或唯一约束 if (exception.getMessage().contains("唯一")) { builder.append("数据已存在:"); } else { builder.append("数据库访问异常:"); } } else { builder.append("非预期的异常:"); } Throwable cause = exception.getCause(); if(cause == null){ builder.append(exception.getMessage()); } else { builder.append(cause); } String msg = builder.toString(); logger.error(msg, exception); HandlerMethod method = (HandlerMethod) handler; ResponseBody responseBody = method.getMethodAnnotation(ResponseBody.class); if (responseBody == null) { ModelAndView view = new ModelAndView("errorView"); view.addObject("msg", msg); return view; } response.setContentType("application/json;charset=UTF-8"); try { new ObjectMapper().writeValue(response.getWriter(), new SimpleJSONResult( false, msg)); } catch (IOException e) { e.printStackTrace(); } return null; } }

    第二步:将HandlerExceptionResolver实现类配置到SpringMVC配置文件中

    <!-- 异常处理 -->
    <bean id="exceptionResolver" class="bdc.base.ExceptionResolver" />

    第三步:针对异常在web.xml统一处理

      <error-page>
        <error-code>404</error-code>
        <location>/error</location>
      </error-page>
      <error-page>
        <error-code>500</error-code>
        <location>/error</location>
      </error-page>
      <error-page>
        <exception-type>java.lang.Exception</exception-type>
        <location>/error</location>
      </error-page>

    第四步:controller接口

      @RequestMapping("/error")
      public ModelAndView error(HttpServletRequest request,
          HttpServletResponse response, Model model) {
        Integer statusCode = (Integer) request
            .getAttribute("javax.servlet.error.status_code");
        Exception exception = (Exception) request
            .getAttribute("javax.servlet.error.exception");
        if (statusCode == null)
          return null;
        StringBuilder builder = new StringBuilder();
        String msg;
        switch (statusCode) {
        case 404:
          msg = builder
              .append(request.getAttribute("javax.servlet.forward.request_uri"))
              .append(",资源不存在").toString();
          logger.warn(msg);
          break;
        default:
          msg = builder.append("非预期的异常:").append(exception.getMessage()).toString();
          logger.error(msg, exception);
          break;
        }
        if (isAjax(request)) {
          response.setContentType("application/json;charset=UTF-8");
          try {
            new ObjectMapper().writeValue(response.getWriter(),
                failureJsonResult(msg));
          } catch (IOException e) {
            e.printStackTrace();
          }
          return null;
        }
        ModelAndView view = new ModelAndView("errorView");
        view.addObject("msg", msg);
        return view;
      } 

      private boolean isAjax(HttpServletRequest request) {
        return "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
      }

     

    以上为全局异常处理

    附加手动抛出异常

    根据不同报错信息实现抛出是业务错误还是什么别的错误

    package bdc.exception;
    
    public class ArgumentRuntimeException extends RuntimeException {
        private static final long serialVersionUID = 1L;
    
        public ArgumentRuntimeException() {
            super();
        }
    
        public ArgumentRuntimeException(String msg) {
            super(msg);
        }
    
        public ArgumentRuntimeException(String msg, Throwable cause) {
            super(msg, cause);
        }
    
        public ArgumentRuntimeException(Throwable cause) {
            super(cause);
        }
    }
    package bdc.exception;
    
    public class BusinessRuntimeException extends RuntimeException {
      private static final long serialVersionUID = 1L;
    
      public BusinessRuntimeException() {
        super();
      }
    
      public BusinessRuntimeException(String msg) {
        super(msg);
      }
    
      public BusinessRuntimeException(String msg, Throwable cause) {
        super(msg, cause);
      }
    
      public BusinessRuntimeException(Throwable cause) {
        super(cause);
      }
    }
    package bdc.exception;
    
    public class UnexpectedRuntimeException extends RuntimeException {
      private static final long serialVersionUID = 1L;
    
      public UnexpectedRuntimeException() {
        super();
      }
    
      public UnexpectedRuntimeException(String msg) {
        super(msg);
      }
    
      public UnexpectedRuntimeException(String msg, Throwable cause) {
        super(msg, cause);
      }
    
      public UnexpectedRuntimeException(Throwable cause) {
        super(cause);
      }
    }

    使用: 

    try {
          //具体业务代码
    } catch (ParseException e) {
          throw new UnexpectedRuntimeException("日期格式错误",e);
    }
  • 相关阅读:
    模板方法模式
    Centos 6.4 python 2.6 升级到 2.7
    Python 在Visual studio 中做单元测试进行TDD开发
    C# 代码转换到Python
    VMware Network Adapter VMnet1和VMnet8 未识别的网络的解决方法
    Visual Studio 启动加速
    查询Sqlserver 表结构信息 SQL
    HTTP发送请求模拟
    【Xamarin 开发 IOS --使用 Storyboard Segue 实作 UIViewController 的切换 (实例)】
    【Xamarin 开发 IOS --IOS 页面导航概念Segue】
  • 原文地址:https://www.cnblogs.com/gaomanito/p/10454709.html
Copyright © 2011-2022 走看看