欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SpringMVC全局异常处理

程序员文章站 2022-04-21 23:48:29
...
  • 在SpringMVC.xml中引入相应的类
<!--配置全局异常处理器-->
<bean class="net.xxx.xxx.common.exception.SpringHandlerExceptionResolver"/>

  • 定义异常枚举类
public enum HttpExceptionEnum {

    NOT_FOUND_EXCEPTION {
        @Override
        public int getCode() {
            return 404;
        }

        @Override
        public String getMessage() {
            return "访问的资源丢失";
        }
    },
    NOT_SUPPORTED_MEDIA_TYPE_EXCEPTION {
        @Override
        public int getCode() {
            return 415;
        }

        @Override
        public String getMessage() {
            return "不支持当前媒体类型";
        }
    },
    NOT_ACCEPTABLE_MEDIA_TYPE_EXCEPTION {
        @Override
        public int getCode() {
            return 500;
        }

        @Override
        public String getMessage() {
            return "响应的类型不一致";
        }
    },
    MISSING_REQUEST_PARAMETER_EXCEPTION {
        @Override
        public int getCode() {
            return 400;
        }

        @Override
        public String getMessage() {
            return "请求参数丢失";
        }
    },
    REQUEST_BINDING_EXCEPTION {
        @Override
        public int getCode() {
            return 500;
        }

        @Override
        public String getMessage() {
            return "请求绑定异常";
        }
    },
    NOT_SUPPORTED_CONVERSION_EXCEPTION {
        @Override
        public int getCode() {
            return 500;
        }

        @Override
        public String getMessage() {
            return "实现类转换失败";
        }
    },
    TYPE_MISMATCH_EXCEPTION {
        @Override
        public int getCode() {
            return 500;
        }

        @Override
        public String getMessage() {
            return "类型不匹配";
        }
    },
    MESSAGE_NOT_READABLE_EXCEPTION {
        @Override
        public int getCode() {
            return 400;
        }

        @Override
        public String getMessage() {
            return "参数解析失败";
        }
    },
    MESSAGE_NOT_WRITABLE_EXCEPTION {
        @Override
        public int getCode() {
            return 500;
        }

        @Override
        public String getMessage() {
            return "参数无效";
        }
    },
    NOT_VALID_METHOD_ARGUMENT_EXCEPTION {
        @Override
        public int getCode() {
            return 400;
        }

        @Override
        public String getMessage() {
            return "参数验证失败";
        }
    },
    MISSING_REQUEST_PART_EXCEPTION {
        @Override
        public int getCode() {
            return 404;
        }

        @Override
        public String getMessage() {
            return "请求丢失";
        }
    },
    BIND_EXCEPTION {
        @Override
        public int getCode() {
            return 400;
        }

        @Override
        public String getMessage() {
            return "参数绑定失败";
        }
    },
    ASYNC_REQUEST_TIMEOUT_EXCEPTION {
        @Override
        public int getCode() {
            return 500;
        }

        @Override
        public String getMessage() {
            return "异步请求超时";
        }
    },
    INVOCATION_TARGERT_EXCEPTION {
        @Override
        public int getCode() {
            return 500;
        }

        @Override
        public String getMessage() {
            return "InvocationTargetException";
        }
    },
    OTHER_EXCEPTION {
        @Override
        public int getCode() {
            return 500;
        }

        @Override
        public String getMessage() {
            return "系统错误";
        }
    },
    NOT_SUPPORTED_METHOD_EXCEPTION {

        @Override
        public int getCode() {
            return 405;
        }

        @Override
        public String getMessage() {
            return "不支持当前请求方法";
        }

    },
    NULL_POINTER_EXCEPTION {

        @Override
        public int getCode() {
            return 404;
        }

        @Override
        public String getMessage() {
            return "空指针异常";
        }

    };

    public abstract int getCode();

    public abstract String getMessage();

    public static HttpExceptionEnum get(int value) {
        for (HttpExceptionEnum exceotion : HttpExceptionEnum.values()) {
            if (exceotion.getCode() == value) {
                return exceotion;
            }
        }
        return null;
    }
}

  • 异常详细输出工具类

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;

/**
 * 异常详细输出工具类
 *
 * @author user
 * @version $Revision: 1.0 $, $Date: 2019年7月18日 上午11:15:28 $
 */
public class ExceptionUtil {
    public static String getExceptionAllinformation(Exception ex) {
        String sOut = "";
        sOut += ex.getMessage() + "\r\n";
        StackTraceElement[] trace = ex.getStackTrace();
        for (StackTraceElement s : trace) {
            sOut += "\tat " + s + "\r\n";
        }
        return sOut;
    }

    public static String getExceptionAllinformation_IO(Exception ex) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        PrintStream pout = new PrintStream(out);
        ex.printStackTrace(pout);
        String ret = new String(out.toByteArray());
        pout.close();
        try {
            out.close();
        }
        catch (Exception e) {
        }
        return ret;
    }

    public static String toString(Throwable e) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw, true);
        e.printStackTrace(pw);
        pw.flush();
        sw.flush();
        return sw.toString();
    }
}

  • springmvc 统一错误处理类
    import java.lang.reflect.InvocationTargetException;
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.commons.lang3.StringUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.ConversionNotSupportedException;
    import org.springframework.beans.TypeMismatchException;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.core.Ordered;
    import org.springframework.http.converter.HttpMessageNotReadableException;
    import org.springframework.http.converter.HttpMessageNotWritableException;
    import org.springframework.validation.BindException;
    import org.springframework.web.HttpMediaTypeNotAcceptableException;
    import org.springframework.web.HttpMediaTypeNotSupportedException;
    import org.springframework.web.HttpRequestMethodNotSupportedException;
    import org.springframework.web.bind.MethodArgumentNotValidException;
    import org.springframework.web.bind.MissingPathVariableException;
    import org.springframework.web.bind.MissingServletRequestParameterException;
    import org.springframework.web.bind.ServletRequestBindingException;
    import org.springframework.web.context.request.async.AsyncRequestTimeoutException;
    import org.springframework.web.multipart.support.MissingServletRequestPartException;
    import org.springframework.web.servlet.HandlerExceptionResolver;
    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.NoHandlerFoundException;
    import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException;
    
    import com.alibaba.fastjson.support.spring.FastJsonJsonView;
    
    /**
     * springmvc 统一错误处理类
     *
     * @author huangzy
     * @version $Revision: 1.0 $, $Date: 2019年7月15日 下午4:35:56 $
     */
    @SuppressWarnings("deprecation")
    public class SpringHandlerExceptionResolver implements HandlerExceptionResolver, Ordered {
    
    
        private static final Logger logger = LoggerFactory.getLogger(SpringHandlerExceptionResolver.class);
    
        // protected static final Logger logger = LoggerFactory.getLogger(SpringHandlerExceptionResolver.class);
    
        /**
         * 设置相应级别
         */
        private int order = Ordered.HIGHEST_PRECEDENCE;
    
        // private FastJsonConfig fastJsonConfig;
        //
        // @Autowired
        // public SpringHandlerExceptionResolver(FastJsonConfig fastJsonConfig) {
        // this.fastJsonConfig = fastJsonConfig;
        // }
    
        private static String domainPath = "";
    
        static {
            if (StringUtils.isBlank(domainPath)) {
    
            }
        }
    
        @Override
        public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
                Exception ex) {
            ModelAndView mv = specialExceptionResolve(ex, request);
            return mv;
        }
    
        /**
         * 这个方法是拷贝 {@link org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver#doResolveException},
         * 加入自定义处理,实现对400, 404, 405, 406, 415, 500(参数问题导致), 503的处理
         *
         * @param ex
         *            异常信息
         * @param request
         *            当前请求对象(用于判断当前请求是否为ajax请求)
         * @return 视图模型对象
         */
        private ModelAndView specialExceptionResolve(Exception ex, HttpServletRequest request) {
            logger.error("Handling of [" + ex.getClass().getName() + "] resulted in Exception", ex);
            try {
                if (ex instanceof NoSuchRequestHandlingMethodException || ex instanceof NoHandlerFoundException) {
                    return result(HttpExceptionEnum.NOT_FOUND_EXCEPTION, request, ex);
                }
                else if (ex instanceof InvocationTargetException) {
                    return result(HttpExceptionEnum.INVOCATION_TARGERT_EXCEPTION, request, ex);
                }
                else if (ex instanceof HttpRequestMethodNotSupportedException) {
                    return result(HttpExceptionEnum.NOT_SUPPORTED_METHOD_EXCEPTION, request, ex);
                }
                else if (ex instanceof HttpMediaTypeNotSupportedException) {
                    return result(HttpExceptionEnum.NOT_SUPPORTED_MEDIA_TYPE_EXCEPTION, request, ex);
                }
                else if (ex instanceof HttpMediaTypeNotAcceptableException) {
                    return result(HttpExceptionEnum.NOT_ACCEPTABLE_MEDIA_TYPE_EXCEPTION, request, ex);
                }
                else if (ex instanceof MissingPathVariableException) {
                    return result(HttpExceptionEnum.NOT_SUPPORTED_METHOD_EXCEPTION, request, ex);
                }
                else if (ex instanceof MissingServletRequestParameterException) {
                    return result(HttpExceptionEnum.MISSING_REQUEST_PARAMETER_EXCEPTION, request, ex);
                }
                else if (ex instanceof ServletRequestBindingException) {
                    return result(HttpExceptionEnum.REQUEST_BINDING_EXCEPTION, request, ex);
                }
                else if (ex instanceof ConversionNotSupportedException) {
                    return result(HttpExceptionEnum.NOT_SUPPORTED_CONVERSION_EXCEPTION, request, ex);
                }
                else if (ex instanceof TypeMismatchException) {
                    return result(HttpExceptionEnum.TYPE_MISMATCH_EXCEPTION, request, ex);
                }
                else if (ex instanceof HttpMessageNotReadableException) {
                    return result(HttpExceptionEnum.MESSAGE_NOT_READABLE_EXCEPTION, request, ex);
                }
                else if (ex instanceof HttpMessageNotWritableException) {
                    return result(HttpExceptionEnum.MESSAGE_NOT_WRITABLE_EXCEPTION, request, ex);
                }
                else if (ex instanceof MethodArgumentNotValidException) {
                    return result(HttpExceptionEnum.NOT_VALID_METHOD_ARGUMENT_EXCEPTION, request, ex);
                }
                else if (ex instanceof MissingServletRequestPartException) {
                    return result(HttpExceptionEnum.MISSING_REQUEST_PART_EXCEPTION, request, ex);
                }
                else if (ex instanceof BindException) {
                    return result(HttpExceptionEnum.BIND_EXCEPTION, request, ex);
                }
                else if (ex instanceof AsyncRequestTimeoutException) {
                    return result(HttpExceptionEnum.ASYNC_REQUEST_TIMEOUT_EXCEPTION, request, ex);
                }
                else {
                    return result(HttpExceptionEnum.OTHER_EXCEPTION, request, ex);
                }
            }
            catch (Exception handlerException) {
                logger.error("Handling of [" + ex.getClass().getName() + "] resulted in Exception", handlerException);
            }
            return null;
        }
    
        /**
         * 判断是否ajax请求
         *
         * @param request
         *            请求对象
         * @return true:ajax请求 false:非ajax请求
         */
        private boolean isAjax(HttpServletRequest request) {
            return "XMLHttpRequest".equalsIgnoreCase(request.getHeader("X-Requested-With"));
        }
    
    
        /**
         * 返回异常信息
         *
         * @param httpException
         *            异常信息
         * @param request
         *            请求对象
         * @return 模型视图对象
         */
        private ModelAndView result(HttpExceptionEnum httpException, HttpServletRequest request, Exception ex) {
            logger.error("请求处理失败,请求url=[{}], 失败原因 : {}", request.getRequestURI(), httpException.getMessage());
            if (isAjax(request)) {
                return jsonResult(httpException.getCode(), httpException.getMessage(), ex);
            }
            else {
                return normalResult(httpException.getMessage(), "ccstudy/pages/common/exception", request, ex);
            }
        }
    
        /**
         * 返回错误页
         *
         * @param message
         *            错误信息
         * @param url
         *            错误页url
         * @return 模型视图对象
         */
        private ModelAndView normalResult(String message, String url, HttpServletRequest request, Exception ex) {
            Map<String, Object> model = new HashMap<String, Object>();
            model.put("sysMessage", message);
            model.put("ex", ExceptionUtil.getExceptionAllinformation_IO(ex));
            return new ModelAndView(url, model);
        }
    
        /**
         * 返回错误数据
         *
         * @param message
         *            错误信息
         * @return 模型视图对象
         */
        private ModelAndView jsonResult(int code, String message, Exception ex) {
            ModelAndView mv = new ModelAndView();
            FastJsonJsonView view = new FastJsonJsonView();
            Map<String, Object> attributes = new HashMap<String, Object>();
            attributes.put("code", code);
            attributes.put("message", message);
            attributes.put("ex", ExceptionUtil.getExceptionAllinformation_IO(ex));
            view.setAttributesMap(attributes);
            mv.setView(view);
            return mv;
        }
    
        @Override
        public int getOrder() {
            return order;
        }
    
        public void setOrder(int order) {
            this.order = order;
        }
    
    }
    

    备注:文章中代码之前开发时,查找文章有复制的内容,现在整理时已找不到原文地址,如作者看到可联系改为[转载]