为了避免可能出现的异常
我们这里大部分方法都用 try-catch 括起来
看起来很难看啊。。。
比如,接收页面传入的整数,传过来是字符串,我们需要用数字的时候,就会 Integer.valueOf()
但是,写页面的人不是同一个,也可能经常换,也可能不同项目组
虽然有文档,但是,不能确保一定会传入整数
为了在可能出问题的时候不会出问题而背锅,我们就需要用上 try catch
有大佬会说使用前验证参数
有时候参很多,每个都去验一次么?
各位大佬有啥好方法么?
![]() | 1 FanError 2020-04-16 18:12:19 +08:00 现在我都是 throw RuntimeException 了,然后全局异常捕获,统一返回报错信息 |
![]() | 2 luckyrayyy 2020-04-16 18:14:33 +08:00 楼上+1,直接抛,全局补 |
![]() | 3 zhuangzhuang1988 2020-04-16 18:15:14 +08:00 <Java8 实战>里这样扯过 P217 public static Optional<Integer> stringToInt(String s) { try { return Optional.of(Integer.parseInt(s)); } catch (NumberFormatException e) { return Optional.empty(); } } 然后再应用 PS: 其实 C#很早就有函数 tryParse https://docs.microsoft.com/en-us/dotnet/api/system.int32.tryparse?view=netframework-4.8 |
![]() | 4 yjxjn 2020-04-16 18:17:25 +08:00 @luckyrayyy 这个全局补怎么说?比如调用某工具类里方法全部抛出异常,然后再调用的 Controller 里面接么?能详细说一下吗? |
![]() | 5 luckyrayyy 2020-04-16 18:19:35 +08:00 @yjxjn ExceptionHandler 注解 |
![]() | 6 asd123456cxz 2020-04-16 18:21:19 +08:00 @yjxjn 如果是 Spring 项目,可以新建一个异常处理类,使用 @ControllerAdvice 注解,默认使用 AOP 构造出针对全部 controller 的代理类,全局处理异常。不过自己写一个切面部分地处理也可以,顺便把日志统计也做了 |
![]() | 7 Jrue0011 2020-04-16 18:26:34 +08:00 Spring MVC 的话,Controller 加 Validated 注解,MVC 本身参数绑定自带的校验再加上校验注解,支持简单参数、Form 对象和 RequestBody 对象,进入方法前入参就校验完了,ControllerAdvice 捕获校验异常统一返回 SmartValidator 格式化后的校验结果,还支持国际化。。。 |
8 superrichman 2020-04-16 18:27:13 +08:00 via iPhone 所有传入的参数都要验证。可以搜搜 java form validation,不需要自己写一堆 try catch |
![]() | 9 Jrue0011 2020-04-16 18:30:30 +08:00 @Jrue0011 另外这样校验也支持分组。。就是入参是同一个 bean 类,这个接口只校验某几个属性,另一个接口校验另外一些属性 |
![]() | 10 limuyan44 2020-04-16 18:35:03 +08:00 全靠全局捕获,自己基本不会用,项目里每个 controller 里面写过 trycatch return 一个自定义 response 我都感觉这帮人没正经学过 spring mvc,框架安排的明明白白的,不需要自己做这种丑陋的写法 |
11 optional 2020-04-16 18:39:01 +08:00 via iPhone lombok |
![]() | 12 loryyang 2020-04-16 19:28:41 +08:00 Spring MVC 直接支持了啊,都不需要你来处理,包括类型和空判断 |
![]() | 13 zhuawadao 2020-04-16 20:18:05 +08:00 |
![]() | 14 araaaa 2020-04-16 22:45:58 +08:00 let it crash |
![]() | 15 xuanbg 2020-04-16 23:01:20 +08:00 一般都是直接抛,然后全局捕获。只有确定需要处理的异常,才 try/catch 起来自己处理掉异常。譬如处理队列消息的时候,异常了要写回死信队列,以免丢消息。 |
16 paragon 2020-04-16 23:38:37 +08:00 关键字 JSR349 ControllerAdvice |
17 mawerss1 2020-04-16 23:42:46 +08:00 via iPhone ![]() 强烈反对上面的把异常 catch 掉返回空值的做法,破坏了语义甚至可能产生一些发现不了的逻辑问题,如果非要 catch,建议再向上层抛出一个定义异常 |
![]() | 18 itechify PRO 这种运行时的,不用管吧,前端传过来错误的,不按照接口定义写,肯定是对方的问题,不是我的问题为啥要管呢 |
![]() | 19 sagaxu 2020-04-17 01:05:30 +08:00 via Android crash early crash often |
![]() | 20 yanyueio 2020-04-17 07:29:30 +08:00 和楼上观点大概类似: * Java Core: 避开 checked 异常这类编译时就强迫你处理的异常,其他异常 let crash 。 * 框架: 比如 Spring 系,全局处理,而且搭建架子的负责人应该会提前制定好规范&模板了。 至于说入参的检验,那要看大家约定的是依靠返回值(json 对象或者其他)来判断还是是依靠抛异常来协商了(类似防御式编程类的官样话),这太灵活了,还是看团队如何约定的。 |
21 orm 2020-04-17 08:10:04 +08:00 目前我用 try catch 最多的就是在一些定时任务上,避免执行过程终端 |
![]() |
25 kanepan19 2020-04-17 09:47:20 +08:00 有事务的地方抛异常, 没事务的地方都抓,抓了把异常放到 resultMsg 放到 result 里返回。 全局异常肯定有,个人不喜欢随便抛。 |
![]() | 26 chendy 2020-04-17 09:52:52 +08:00 工具类里写挺多的,吃掉一些不可能出现的 checked exception (然后抛一个自定义 unchecked exceptoin ),比如加密算法没找到,编码未找到这种… |
27 yeqizhang 2020-04-17 10:52:52 +08:00 via Android 不是用户填的东西的话,没必要,和前端调通了之后一般没有问题,有问题也是要找为啥数据会错。 如果是用户填的,前端先检验,然后后端也要做检验或者捕获异常,我遇到测试测接口直接传不符合的数据然后提 bug 的 |
![]() | 28 mosliu 2020-04-17 11:03:04 +08:00 用 common lang3 的 NUmberUtils 的 toInt 不行么? 错误的转出来个默认值 检查直接返回错误。 |
![]() | 29 aitaii 2020-04-17 11:22:27 +08:00 @xiaofan2 继承 RuntimeException 的自定义业务异常,ExceptionHandler 里处理异常信息 |
30 sunxiansong 2020-04-17 11:44:57 +08:00 插一下嘴。。 之前写 java,try catch 用的不多,反正有毛病都抛出去。 现在写 go, 各种 ```go if err != nil { return err } ``` 遇到返回结果有 error 的都要这么来一下,复杂点的函数能来好几次 觉得 java 的话,对于需要特别识别的错误,可以检查下,不然就直接抛出吧,大部分正常流程能走通就行 有些函数声明的异常甚至几乎不会出现,追求完善的错误处理覆盖是不现实的,还不如完善错误监控处理机制,避免隐式错误处理、错误遗漏,定期的检查错误情况再完善代码 如果只是不喜欢 try catch 风格,那自己搞一套错误-结果返回方案就行 |
31 EminemW 2020-04-17 12:38:05 +08:00 我有个疑问,这个抛异常会影响性能吗,之前不知道在哪里看过不要随便抛异常。。我的做法的是 return Result.error(code, msg); |
32 chanchan 2020-04-17 12:43:51 +08:00 via Android 很多地方需要写,但是懒得写 |
![]() | 33 lihongming 2020-04-17 13:43:03 +08:00 via iPhone 拿异常当日常反馈的路过。 只要数据不合格就抛异常出去,调用方不 try catch 怎么活啊? |
34 yukiloh 2020-04-17 15:06:00 +08:00 via Android 以前自己喜欢扔,后来看到哪里说能抓尽量当下抓,不能的再扔,给搞迷糊了 |
![]() | 35 purensong 2020-04-17 15:31:49 +08:00 定义一个 @ControllerAdvice 修饰的全局异常处理类,实现多个方法加上 @ExceptionHandler(value = Exception.class) 注解,value 是 Exception 的子类,例如要检查必须的字段传入,用 MethodArgumentNotValidException,具体的字段不能为空用 @NotNull 注解。 这是通用的异常处理,如果还有业务异常,需要自定义异常类,我习惯直接在代码里抛出自定义异常,也都交由全局异常类去特殊处理 |
![]() | 36 purensong 2020-04-17 15:34:07 +08:00 可以说代码里 try catch 可能都是连接消息关闭,文件不存在这些代码,很少会出现类型检查这种低级别的捕获,这种检查代码大量存在,而且级别较低,不会有出现异常后的处理,基本就是报错提示到前端就没有了。 |
![]() | 38 xiangyuecn 2020-04-17 16:53:10 +08:00 转换成 int 时,返回 Integer 类型,要么返回一个数要么,返回一个 null,拒绝使用 try catch byte 统一用 short 类型,拒绝负数 ( doge |
39 vwym 2020-04-17 17:27:32 +08:00 web 项目就直接抛出去全局处理了,参数验证可以考虑用 Validations 注解完事。 不做 try catch |
![]() | 40 Mystery0 2020-04-18 11:59:38 +08:00 via Android @EminemW 确实有一点影响,不过照你的这样子返回 Result.error(code, msg),调用深了以后,每一层都要去做执行结果的判断,写着写着就变成手写 Java 的异常处理机制了 |
41 NoKey OP @pabno 遵守接口约定,按照文档规定写代码,这个要看公司文化,强制执行的的,谁出问题问责谁这没问题,但是有些公司,会把涉及的人都弄出来批一次。。。什么,他传错了参数?他传错参数,你代码不会鉴别?你代码就死在里面了?你这是什么代码?有些公司强绩效,为了不扣分,谨小慎微,尽量避免问题出在自己这一块 |
42 pabno 2020-04-23 16:15:07 +08:00 @NoKey 我的意思就是提前校验,让他不能传约定外的参数类型。这种如果客户端传了约定外的类型,那在测试阶段就要把这个问题暴露出来 |
43 notwaste 2020-04-29 15:25:13 +08:00 可以去看下 Hibernate validator |
44 xinQing 2020-05-13 18:20:09 +08:00 Hibernate validator 校验参数;抛出异常,全局处理。 同一楼、二楼 |