记一次线上bug
今天3.8妇女节有个我负责的活动上线使用了,大部分的用户使用正常,但是有少量用户反馈问题到了我这里。记录一下,希望以后能写出健壮性强的代码。
查找bug
找bug主要就是看日志,项目是使用docker部署的,所以使用
docker logs -f cssp_game | grep Exception
查看日志中抛出的异常,把Exception改成Error就可以查找错误。然后大部分是业务异常,其中有一部分不太正常:
java.lang.IllegalArgumentException: Invalid character found in the request target
[game/run38_user/save_user?address=%E6%97%A0%E9%94%A1%E5%B8%82%E6%BB%A8%E6%B9%96%E5%8C%BA%E6%B2%B3%E5%9F%92%E8%A1%97%E9%81%93%E8%A0%A1%E6%88%90%E6%9D%911-502
&awardId=2&deptId=18
&headImage=https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKfEXD4Qic6xXMavPsensNkWW4wyUqDiaicdsdEiaeI7KQHcpwIYPAVDiakqHoibLXryXBBHR4yFnRyAM4g/132&jobNumber=30412
&nickName=%E6%BA%90^o^
&openId=oLwc_IN6-wTjXqcn65ZAi1Z_4&unionId=10 ].
The valid characters are defined in RFC 7230 and RFC 3986
显示有非法字符,然后这是一个拼接起来的url出现不合法字符,接口肯定就不能正常接收到参数。 查找资料知道:
不安全字符
还有一些字符,当他们直接放在Url中的时候,可能会引起解析程序的歧义。这些字符被视为不安全字符,原因有很多。
空格 | Url在传输的过程,或者用户在排版的过程,或者文本处理程序在处理Url的过程,都有可能引入无关紧要的空格,或者将那些有意义的空格给去掉 |
---|
引号以及<> | 引号和尖括号通常用于在普通文本中起到分隔Url的作用 | # | 通常用于表示书签或者锚点 | {}^[]`~ | | 某一些网关或者传输代理会篡改这些字符 | % | 百分号本身用作对不安全字符进行编码时使用的特殊字符,因此本身需要编码 |
其他字符可见:url中的特殊字符
排除bug
而解决这个bug的方法一方面可以让前端在拼接url的时候对字符进行加密再传给后端。但是根本原因在于我写代码的时候没有考虑到这个问题,导致健壮性不强。见代码:
@ApiOperation("保存领取奖品的用户")
@PostMapping("/save_user")
public Message userInfo(UserDTO userDTO) {
}
Post方法支持在url中拼接和requestBody中传参,因为没有指定哪种方式,导致swagger默认是拼接的参数,所以在昵称中或者地址中有不安全字符时就报异常。所以可以在参数前加入@RequestBody 就可以指定前端通过requestBody传json格式参数,此时后端再进行解析。对于@RequestBody和@RequestParam的使用和区别可以见:@RequestBody和@RequestParam的使用和区别
总结
在写代码时对数据库进行写时尽量使用@PostMapping + @RequestBody + @Transactional(rollbackFor = Exception.class)(有异常回滚),查询时尽量使用@GetMapping或者@PostMapping + @RequestParam。而且在对String(varchar)类型的列查询时尽量使用like模糊搜索一下防止出现空格,导致使用=时找不到的原因。
|