发表于: 2017-10-18 21:53:32
1 808
一.今天完成的主要事情
1.整理收集小课堂的相关资料和知识点
对Service返回的结果是否要判空,为什么?是否要打日志,应该打什么样的日志,为什么?
背景介绍:最近在做复盘,写接口的时候,业务实现的逻辑代码没有多少,但是整个接口的代码量却不少,举个例子,一个简单的根据条件查询产品表,获取idList,然后再通过idList获取产品对象List,最后返回前端数据的接口,代码却有将近80行,原因就在于有相当多的代码都在判断参数是否为空,是否正确等.
知识剖析:
整合为三个问题
对于接口的入参,判断是否为空,参数是否正确很正常,但是调用Service之后返回的结果是否要判空呢?原因是什么?
调用Service返回的结果需不需要打日志?
如果要打的话,应该打什么样的日志?
问题1:分情况,调用Service之后返回的结果通常有两种用途,一种是作为最后的结果返回,还有一种是作为下一个操作的入参.如果是下一个操作的入参,那么就必须要判空;如果是作为最后的结果返回,还要再继续细分,如果这个结果可以为空,那么就不用判断,直接返回;如果这个结果不能为空,那么还要继续判断,并要处理异常情况(代码演示一遍,productController)
接口中日志的主要作用:快速定位问题的根源,追踪程序执行的过程,追踪数据的变化,数据统计和性能分析
问题2:需要.目前在项目中,所有的从Service返回的结果都要打日志.这个问题很好理解,日志是我们了解程序运行,问题追踪的工具.如果从Service返回的结果不打日志,以后出现问题,我们就不能快速的定位到问题所在.举个例子,通过代码演示一遍(messageController)
问题3:这个也要分情况,有以下几种情况:通常返回的数据有以下几种情况
1. 是一个基本类型或者对象类型,比如通过条件获取ID,或者根据Id获取对象等.这是要分为两种情况, ,一种是我只需要该对象的属性,比如是否为空,具体返回的数据的值是什么,我们不关心的,就不需要在日志中打印返回的结果的值(代码举例,userController);
还有一种是我除了要判断该对象的属性,还需要用到该数据的值,比如作为结果返回,或者是作为下一步操作的入参,那么就需要在日志中打印结果,以后如果出现问题,能够方便我们进行调试.
打印对象类型时还要注意,不能将一些敏感信息打印,比如用户的密码,身份证信息等
2. 是一个集合,比如数组,List等,这种如果没有特殊需求,只需要打印List的长度即可,不需要将所有的list中数据的具体值记录日志,因为这样会特别影响性能,而且打印长度基本也满足了我们对日志功能的需求.
扩展思考:日志包括哪些要素?
日期,时间(有的要求高的还要提供毫秒信息和时区);会话标识;日志级别;日志内容
日志内容包括上下文,不要只有一个Error,或者success最好是能够简单描述一下原因(代码实例)
2.完成【我的】story的编写
主要完成用户申请实名认证接口,更新用户详情接口,以下是用户申请实名认证接口
/**
* 24.用户实名认证
*
* @param:
* @return
* @throws ServiceException
* @throws ServiceDaoException
*/
@RequestMapping(value = "/a/u/identify/{id}", method = RequestMethod.PUT)
public String identifyUser(HttpServletRequest request,
HttpServletResponse response, ModelMap model, @PathVariable Long id,
String name, String IDNo, String IDCardImgFacade, String IDCardImgObverse) throws Exception {
log.info("identifyUser() parameters: id : " + id + ", name : " +name + ", IDNo : " + IDNo +
"IDCardImgFacade : " + IDCardImgFacade + "IDCardImgObverse" + IDCardImgObverse);
//验证传入的参数的正确性
int identifyResult = UserUtil.validateUserIdentify(name, IDNo,IDCardImgFacade,IDCardImgObverse);
if (identifyResult != 1){
log.info("illegal parameter, identifyResult : " + identifyResult);
model.addAttribute("code", identifyResult);
return "/common/failure";
}
Verification verification = new Verification();
try{
//验证该身份证号是否使用过
Long userId = userService.getUserIdByIDNo(IDNo);
if (DataUtils.isNotNullOrEmpty(userId)){
log.info("ERROR: ID number is repeated!");
model.addAttribute("code", -2023);
return "/common/failure";
}
//验证id是否正确
User user = userService.getObjectById(id);
if (DataUtils.isNullOrEmpty(user)){
log.info("Couldn't find user by id, id is : " + id);
model.addAttribute("code", -4);
return "/common/failure";}
//打印用户部分信息,因为有密码,所以不能直接打印对象
log.info("get user part data : " + "id : " + user.getId() + ", name : " + user.getName()
+ ", cellphone: " + user.getCellphone() + ", userSerialNumber : " + user.getUserSerialNumber()
+ ", createAt: " + user.getCreateAt() + ", updateAt: " + user.getUpdateAt());
//验证字段verification的值是否正确
Integer verificationField = user.getVerification();
log.info("get field verification from user, verification is :" + verificationField);
if (DataUtils.isNullOrEmpty(verificationField)){
log.info("Field verification of user can not be NULL");
model.addAttribute("code", -40002);
return "/common/failure";
}
//verification为1说明该用户已经验证成功
if (verificationField == 1){
log.info("already identify, can not commit identify info again");
model.addAttribute("code", -2032);
return "/common/failure";
//verification为0说明用户还没有验证成功,继续下一步的验证
} else if (verificationField == 0){
List<Long> verificationIds = verificationService.getVerificationIdsByUserId(id, 0, Integer.MAX_VALUE);
log.info("get verification ids , ids : " + verificationIds);
//如果不为空,说明有验证记录,继续验证
if (DataUtils.isNotNullOrEmpty(verificationIds)){
List<Verification> verifications = verificationService.getObjectsByIds(verificationIds);
log.info("get verification data count : " + verifications.size());
for (Verification v: verifications) {
//如果该用户的认证记录中有未认证或者已认证的记录,则不允许再继续认证
if (v.getVerifiedStatus() == 1 || v.getVerifiedStatus() == 0){
log.info("identify ing, can not add identify info again");
model.addAttribute("code", -2033);
return "/common/failure";
}
}
}
log.info("Insert a record in the verification table ");
verification.setUserId(id);
verification.setVerifiedStatus(0);
verification.setRefusedReason("");
verification.setCreateBy(id);
verification.setUpdateBy(id);
verification.setCreateAt(System.currentTimeMillis());
verification.setUpdateAt(System.currentTimeMillis());
Long verificationId = verificationService.insert(verification);
model.addAttribute("code", 0);
model.addAttribute("id", verificationId);
} else {
log.info("Field verification's value is incorrect");
model.addAttribute("code", -40003);
return "/common/failure";
}
} catch (Throwable t){
t.printStackTrace();
log.error(t.getMessage());
log.error("identify user error,user id is " + id);
model.addAttribute("code", -1);
}
return "/common/success";
}
二.明天计划完成的事情
1.开始【投资列表页】story的编写,先写出来查询用户投资的产品列表和查询用户投资的产品详情接口
2.准备完善小课堂
三.遇到的问题
暂无
四.收获
对接口中打日志的方式有了更加深入的理解
五.项目进度情况
有延期风险
评论