需求:
在项目开发中,经常会遇到一些参数验证,当然,在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中。