Spring项目中优雅的异常处理
前言
如今的Java Web项目多是以 MVC 模式构建的,通常我们都是将 Service 层的异常统一的抛出,包括自定义异常和一些意外出现的异常,以便进行事务回滚,而 Service 的调用者 Controller 则承担着异常处理的责任,因为他是与 Web 前端交互的最后一道防线,如果此时还不进行处理则用户会在网页上看到一脸懵逼的
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4 at cn.keats.TestAdd.main(TestAdd.java:20)
这样做有以下几点坏处:
- 用户体验很不友好,可能用户会吐槽一句:这是什么XX网站。然后不再访问了
- 如果这个用户是同行,他不仅看到了项目代码的结构,而且看到抛出的是这么低级的索引越界异常,会被人家看不起
- 用户看到网站有问题,打电话给客服,客服找到产品,产品叫醒正在熟睡/打游戏的你。你不仅睡不好游戏打不了还得挨批评完事改代码
哎,真惨。因此一般我们采用的方法会是像这样:
异常处理
一般的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 }