前言

如今的Java Web项目多是以 MVC 模式构建的,通常我们都是将 Service 层的异常统一的抛出,包括自定义异常和一些意外出现的异常,以便进行事务回滚,而 Service 的调用者 Controller 则承担着异常处理的责任,因为他是与 Web 前端交互的最后一道防线,如果此时还不进行处理则用户会在网页上看到一脸懵逼的

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4     at cn.keats.TestAdd.main(TestAdd.java:20)

这样做有以下几点坏处:

  1. 用户体验很不友好,可能用户会吐槽一句:这是什么XX网站。然后不再访问了
  2. 如果这个用户是同行,他不仅看到了项目代码的结构,而且看到抛出的是这么低级的索引越界异常,会被人家看不起
  3. 用户看到网站有问题,打电话给客服,客服找到产品,产品叫醒正在熟睡/打游戏的你。你不仅睡不好游戏打不了还得挨批评完事改代码

哎,真惨。因此一般我们采用的方法会是像这样:

异常处理

一般的Controller处理

Service代码如下:

@Service public class DemoService {     public String respException(String param){         if(StringUtils.isEmpty(param)){             throw new MyException(ExceptionEnum.PARAM_EXCEPTION);         }         int i = 1/0;         return "你看不见我!";     } }

Controller代码如下:

@RestController public class DemoController {     @Autowired     private DemoService demoService;          @PostMapping("respException")     public Result respException(){         try {             return Result.OK(demoService.respException(null));          } catch (MyException e){             return Result.Exception(e, null);         }         catch (Exception e) {             return Result.Error();         }     }  }

如果此时发送如下的请求:

http://localhost/respException

服务器捕捉到自定义的异常 MyException,而返回参数异常的Json串:

{     "code": 1,     "msg": "参数异常",     "data": null }

而当我们补上参数:

http://localhost/respException?param=zhangsan

则服务器捕捉到 by zero 异常,会返回未知错误到前端页面

{     "code": -1,     "msg": "未知错误",     "data": null }