Java 全局异常处理

需求:

在项目开发中,经常会遇到一些参数验证,当然,在controller层中可以使用java扩展包中的@Valid进行验证,但是在一些比较复杂的逻辑中,或者和第三方交互中产生的值需要校验时,通过创建返回创建的实体bean太过繁琐,用map封装也太杂乱,故自己打算创建一个Exception,既可以进行自己逻辑的判断,又可以对不友好的提示,进行修饰。

恩,网上看的一个比较合理的需求解释感觉很符合情况的。。。。。

JavaWeb应用开发中产生的异常都应该继承Exception(属于checkedexcpetion类型)。而且JavaWeb应用一般采用三层或多层架构,程序员没有必要在各个层中对错误和异常进行处理,应用中的每一层在包装并传递异常时要过滤掉Runtime-Exception,从责任这个角度看uncheckedexception是程序应该负担的责任;checkedexception是具体应用负担的责任。无论如何我们都不应该将uncheckedexception这样的异常暴露给客户的,因为他们没有解决这个问题的责任,应该将这种异常封装成checkedexception类型的异常,由具体的应用程序来负担这个责任。

分析:

在目前的JavaWeb开发中,开发基础是Spring,普遍的开发框架就是基于SpringMvc的,比如说springMVC+mybatis/+Hibernate,甚至现在比较流行的springBoot、SpringCloud都是基于SpringMVC进行开发的。 当然,一些老项目还在用ssh、SSM,但是新项目开发基本不做选择了。

而在SpringMVC中,处理异常信息的类都实现了HandlerExceptionResolver接口。

HandlerExceptionResolver 可以说是SpringMVc中处理异常的最最基本的接口,并不是说非他不可,但是想处理异常最简便的方法还是创建一个属于自己的Resolver 实现其对应的方法就可以了。

在一个项目中,可以有多个处理异常的类,所以在处理异常的时候需要进行优先级的判断,这个需要实现Order的接口,根据其order值来进行优先级的判断,值越小优先级就越高。AbstractHandlerExceptionResolver就是实现了两者的基类,所以在考虑多个处理异常的类时可以直接继承这个类,也可以自己去实现一个与之相似的类。

在这里,个人认为没有必要去进行多个异常处理类,所以只是简单地实现了一个Resolver.

exception分析:

在java中,Throwable是所有错误的父类,其可以分为error和Exception 连个分支。懂java的都知道Error是java内部错误,和我们程序员程序开发没关系,与我们相关的就是一些“意外”(Exception),所谓的exception就是 正常程序运行的意外。Exception 又分为 运行时异常RuntimeException和编译时异常(有的也叫IO异常,编译异常就是项目变异就出现的错误,新出现后项目不能运行,所已在开发中我们要着重对待运行时异常,所以在创建自己的异常的时候需要进行集成最基本的RuntimeException.

实现

创建属于自己的异常类

@Data
@Builder
public class BaseException extends RuntimeException {
    private String errorCode;
    private String errorMsg;
    private Object causeInfo;

    public BaseException(){}

    public BaseException(String errorCode, String errorMsg) {
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
    }

    public BaseException(String errorCode, String errorMsg, Object cause) {
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
        this.causeInfo = cause;
    }
}

创建自己的Resolver

@Configuration
public class ExceptionHandlerResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        ModelAndView view  = new ModelAndView(new MappingJackson2JsonView());
// 判断是否是自己创建的异常
        if (ex instanceof BaseException) {
            BaseException businessException = (BaseException) ex;
            view.addObject("errorCode", businessException.getErrorCode());
            view.addObject("errorMsg", businessException.getErrorMsg());
        } else {
//不是自己创建的异常就简单处理下
            view.addObject("errorMsg", ex.getMessage());
            view.addObject("errorCode",3002);
        }
        jsonp(request,response);
        return view;

    }


    protected void jsonp(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        String origin = httpServletRequest.getHeader("Origin");
        httpServletResponse.setHeader("Access-Control-Allow-Origin", origin);
        httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACES");
        httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
//        httpServletResponse.setHeader("Access-Control-Max-Age", "3600");
//        httpServletResponse.setHeader("Access-Control-Allow-Headers", "x-requested-with");
    }
}

使用:

在程序的任何地方都可以直接Throw一个自己创建的异常了。样子就是Throws(new BaseException()).

自己创建的resolver,创建后会自动覆盖默认的处理器,并通过@Configation 注入到Spring中。

猜你喜欢

转载自blog.csdn.net/weixin_40458996/article/details/82661573