为了避免可能出现的异常
我们这里大部分方法都用 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 1
强烈反对上面的把异常 catch 掉返回空值的做法,破坏了语义甚至可能产生一些发现不了的逻辑问题,如果非要 catch,建议再向上层抛出一个定义异常
|
18
oneisall8955 2020-04-17 00:56:03 +08:00 via Android
这种运行时的,不用管吧,前端传过来错误的,不按照接口定义写,肯定是对方的问题,不是我的问题为啥要管呢
|
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 最多的就是在一些定时任务上,避免执行过程终端
|
22
gwybiaim 2020-04-17 08:37:37 +08:00
|
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 可能都是连接消息关闭,文件不存在这些代码,很少会出现类型检查这种低级别的捕获,这种检查代码大量存在,而且级别较低,不会有出现异常后的处理,基本就是报错提示到前端就没有了。
|
37
pabno 2020-04-17 16:44:42 +08:00
1. 从项目整体质量的角度出发,接口约定就应该遵守,如果不是强制约束,即使后端可以兼容这种数据格式,前段指不定也会因为数据格式的不一致而引发新的问题,提前暴露问题会减少修正错误的成本
2. 后端参数验证可以使用校验框架写表达式自动校验,然后统一捕获校验异常返回统一数据 |
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 校验参数;抛出异常,全局处理。
同一楼、二楼 |