在springcloud中进行统一异常+自定义异常处理?

1.什么是统一异常处理?

      软件开发过程中,不可避免的是需要处理各种异常,就我自己来说,至少有一半以上的时间都是在处理各种异常情况,所以代码中就会出现大量的try {...} catch {...} finally {...} 代码块,不仅有大量的冗余代码,而且还影响代码的可读性。再回到我们的微服务中,我们也是使用这样的形式处理异常,那么我们导入文件的时候某列的数据不符合我们的标准,我们就可以自定义异常进行处理抛出,用户就会看到我们的友好提示(自定义的异常提醒),而不是看到一些异常信息.

2.怎么进行自定义异常处理?

首先我们得定义自己的异常信息,下面ApplicationException类,然后我们定义一些变量,比如信息类型:1警告 2错误 我们正常导入excel的警告提示,我们是不应该直接抛出异常信息的,这样就需要我们自己做统一异常处理.这儿我们就定义一个字段  是否记录到系统.这儿我们做一个自定义的拦截器来拦截我们项目中的异常抛出,这儿我们定义一个拦截器GlobalDefaultExceptonHandler来处理异常.这儿需要普及一下,我知道处理异常的方式有三种.

第一:使用该注解有一个不好的地方就是:进行异常处理的方法必须与出错的方法在同一个Controller里面。使用如下:

@Controller      
 2 public class GlobalController {               
 3 
 4    /**    
 5      * 处理myexception异常的方法    
 6      * @return    
 7      */      
 8     @ExceptionHandler({MyException.class})       
 9     public String exception(MyException e) {       
10         System.out.println(e.getMessage());       
11         e.printStackTrace();       
12         return "exception";       
13     }       
14 
15     @RequestMapping("testMyException")       
16     public void test() {       
17         throw new MyException("我们自己的异常出问题了!");       
18     }                    
19 }     

      从上面的简单的应用,我们可以看出, 这种处理异常的方式确实可以使用,但是需要写在出错方法的同一个controller里, 并不是我们想要的统一异常处理pass掉

第二: 使用 @ControllerAdvice+ @ ExceptionHandler 注解 进行异常处理

上面我们说到 @ ExceptionHandler 需要进行异常处理的方法必须与出错的方法在同一个Controller里面。那么当代码加入了 @ControllerAdvice,则不需要必须在同一个 controller 中了。这也是 Spring 3.2 带来的新特性。从名字上可以看出大体意思是控制器增强。 也就是说,@controlleradvice + @ ExceptionHandler 也可以实现全局的异常捕捉。代码演示如下:

1 @ControllerAdvice
 2 @ResponseBody
 3 public class WebExceptionHandle {
 4     private static Logger logger = LoggerFactory.getLogger(WebExceptionHandle.class);
 5     /**
 6      * 400 - Bad Request
 7      */
 8     @ResponseStatus(HttpStatus.BAD_REQUEST)
 9     @ExceptionHandler(HttpMessageNotReadableException.class)
10     public ServiceResponse handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
11         logger.error("参数解析失败", e);
12         return ServiceResponseHandle.failed("could_not_read_json");
13     }
14     
15     /**
16      * 405 - Method Not Allowed
17      */
18     @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
19     @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
20     public ServiceResponse handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
21         logger.error("方法不允许", e);
22         return ServiceResponseHandle.failed("request_method_not_supported");
23     }
24 
35     /**
36      * 500 - Internal Server Error
37      */
38     @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
39     @ExceptionHandler(Exception.class)
40     public ServiceResponse handleException(Exception e) {
41         if (e instanceof BusinessException){
42             return ServiceResponseHandle.failed("BUSINESS_ERROR", e.getMessage());
43         }
44         
45         logger.error("服务器内部异常", e);
46         e.printStackTrace();
47         return ServiceResponseHandle.failed("server_error");
48     }
49 }

          第三:实现HandlerExceptionResolver 接口进行异常处理,啥也不用说,看代码纯手敲代码 没有复制过来 可能会敲错)

@RestControllerAdvice
public class GlobalDefaultExceptionHandler implements HandlerExceptionResolver{
    @AutoWired
    BizCommonService BizCommonService;//处理异常日志service  根据自己的系统需要是否存储
    
    @Override
    Public ModelAndView resolveException (HttpServletRequest request,                 
     HttpServletResponse, Object handler, Exception e ){
        ModelAndView model = new ModelAndView();
        if(hand instanceof HandlerMethod){
            HandlerMethod hand = (HandlerMethod)handler;
            Method method = hand.getMethod();
            String methodName = method.getName();
            //通过反射获取该controller方法中是否重写了getMenuName方法 为了获取菜单名
            Class<?> beanType = hand.getBeanType;
            String menuName ="";
            try{
                Object newInstance = beanType.newInstance();
                Method method2 = beanType.getMethod("getMenuName");
                Object invoke = method2.invoke(newInstance);
                menuName = invoke.toString();
            }catch(Exception eee){
                menuName = "未重写获取菜单的方法";
            }
       
            if(e instanceof ApplicationException){//ApplicationException属于我们自定义的异常类 
                //属于自定义异常
            }else{
               //使用我们自定义的bizCommonService 进行保存异常信息  异常方法 异常claas类 异常信息
            }

        }
       
        
    }




}

很显然我们项目中用的是实现HandlerExceptionResolver的方法进行了异常处理。

最后奉献上ApplicationException自定义的异常类

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值