前言
大家好,我是田螺。
最近代码评审,因为需求比较紧急,存在一些bad smell的代码。尤其参数校验这一块。
因此,再回头梳理代码评审,有关于参数这块,要注意的点~~
- 公众号 :捡田螺的小男孩 (有田螺精心原创的面试PDF)
- github地址,感谢每颗star:github
1.参数枚举范围尽量不要存在魔法值
反例:
ini
@FieldScope(in={"APP","PORTAL"},message="source is not in scope")
private String source;
正例:
ini
@FieldScope(in={SOURCEEnum.Constant.APP,SOURCEEnum.Constant.PORTAL},message="source is not in scope")
private String source;
2. 同一个参数字段,在不同接口,长度不要不一致
我们代码评审的时候,发现同一个渠道号字段channelCode,在A接口,定义的最大长度是32,但是在B接口,最大长度是16。。。
然后,在数据库存储的时候,是verchar(32).
这个最大长度,最好就是数据库的最大长度~
arduino
@Length(max=32,message ="渠道号超长了")
private String channelCode;
3.判断非空尽量用@NotBlank
之前一个版本,测试给我提了一个bug,说一个来源字段,传个空字符串,也能更新成功,建议做一下校验。
但是呢,我记得代码应该是加了注解校验的:
ini
@NotEmpty(message = "source must not be empty")
private String source;
如果传空字符串的话,@NotEmpty并不能校验出来。源码如下:
typescript
public static boolean isEmpty(CharSequence cs) {
return cs == null || cs.length() == 0;
}
正例应该要用@NotBlank,它可以拦截空字符串。
arduino
public static boolean isBlank(CharSequence cs) {
int strLen = length(cs);
if (strLen == 0) {
return true;
} else {
for(int i = 0; i < strLen; ++i) {
if (!Character.isWhitespace(cs.charAt(i))) {
return false;
}
}
return true;
}
}
4. 代码请求响应跟接口文档要一致
最近我们这疯狂抓接口文档这一块的bug。
比如:
- 你接口本次需求新增一个字段返回,但是你忘记登记在接口文档,那记一个bug。
- 如果你接口新增参数,校验长度没备注到接口文档,也要记录一个bug
- 如果你接口新增参数,做了枚举范围,没备注到接口文档,还要记录一个bug
因此,做好编码这件事情,我们还是要保持好习惯。每次修改接口请求和响应代码时,记得同步更新一下接口文档~~
5. 请求参数都做好校验
我们在开发一个接口的时候,所有参数都确认好是否要做这几个校验:非空、长度、取值范围
还有些特殊情况,就是你这个参数可以传空,但是如果传非空的话,需要校验长度的,这些大家都注意一下哈:
arduino
@Length(max=32,message ="渠道号超长了")
private String channelCode;
如果既不能为空又不能超长,需要这样:
less
@NotBlank(message = "channelCode不能为空")
@Length(max=32,message ="渠道号超长了")
private String channelCode;
6. 参数入口不要太多,太多要用对象包兜住
反例:
less
@PostMapping("/create")
public ResponseEntity<String> createOrder(
@RequestParam String productId,
@RequestParam int quantity,
@RequestParam String shippingAddress) {
// 处理订单逻辑
return ResponseEntity.ok("Order created successfully");
}
正例:
typescript
@PostMapping("/create")
public ResponseEntity<String> createOrder(@RequestBody OrderRequest orderRequest) {
// 处理订单逻辑
return ResponseEntity.ok("Order created successfully");
}
public class OrderRequest {
private String productId;
private int quantity;
private String shippingAddress;
}
7. 参数的长度、非空、范围尽量用注解
反例:
scss
if(StringUtils.isBlank(channelCode)){
//throw Exception
}
if (channelCode.length() > 32) {
//throw Exception
}
正例子:
less
@NotBlank(message = "channelCode不能为空")
@Length(max=32,message ="渠道号超长了")
private String channelCode;
8. 参数校验这一块开发完,最好都自测一下
有些伙伴,觉得参数校验很简单,就不自测了,其实很多隐藏的坑~~
我举个例子,比如@Valid放错位置,会导致校验失效~~ 我在我的踩坑专栏,专门说过这个问题的~~
9、最好做鉴权校验
比如你开发一个查询接口,你要查用户的订单。如果接口时给APP端用的,肯定需要做鉴权校验,就是校验这个用户是否存在、是否已经注销了。然后再做查询~~
10. 参数要做好注释
其实,写代码的时候,没有必要写太多的注释,因为好的方法名、变量名,就是最好的注释。以下就是笔者总结的一些注释规范:
- 所有的类都必须添加创建者和创建日期,以及简单的注释描述
- 方法内部的复杂业务逻辑或者算法,需要添加清楚的注释
- 一般情况下,注释描述类、方法、变量的作用
- 任何需要提醒的警告或TODO,也要注释清楚
- 一块代码逻辑如果你站在一个陌生人的角度去看,第一遍看不懂的话,就需要添加注释了
回到请求参数注释这一块的话,建议就是每个字段都加下注释吧,如下:
less
/**
* 渠道编码,传如1000、2000
*/
@NotBlank(message = "channelCode不能为空")
@Length(max=32,message ="渠道号超长了")
private String channelCode;