关于校验,以往的做法一般是通过if分支做判断,代码容易冗余。本文采用的方法是先定义原子逻辑较验方法,然后将其组装到list列表中,统一顺序执行,如果有一个不满足条件则跳出判断逻辑
public void doReopenOffer(@FormGroup(name = "postBuyOffer") BuyOfferParam buyOfferParam,
HttpServletRequest request, Navigator navigator, Context context) {
try {
String memberId = buildInsertParam(buyOfferParam);
WebCheckValidtor validtor = buyOfferValidatorFactory.getSubmitPostBuyOfferValidator(memberId,
buyOfferParam, true);
Result ret = validtor.validate();
if (!ret.isSuccess()) {
context.put(ERROR_MESSAGE, ret.getResultCode().getMessage());
return;
}
// 重发清除旧数据
buyOfferParam.setId(null);
buyOfferParam.setSign(0);
insertBuyOffer(buyOfferParam, navigator, context);
} catch (Exception e) {
log.error("buyOfferParam:" + buyOfferParam, e);
navigator.forwardTo("error.vm");
}
}
标红的表示:1.获取校验逻辑 2.执行校验过程,得到结果
public WebCheckValidtor getSubmitPostBuyOfferValidator(final String memberId, final BuyOfferParam buyOfferParam,
final boolean isReopen) {
return new WebCheckValidtor() {
private LinkedList<WebCheckValidtor> validatorList = new LinkedList<WebCheckValidtor>();
@Override
public ValidatorResult validate() {
// 构造验证链
validatorList.add(checkMemberExistValidator(memberId));
validatorList.add(getOfferPublishForbidValidator(memberId));
validatorList.add(getIndustryExistValidator(buyOfferParam.getIndustryId()));
validatorList.add(getTimeLimitedValidator(buyOfferParam.getGmtQuotationExpire(),
buyOfferParam.getGmtOrderComfirm(),
buyOfferParam.getGmtReceive()));
if (isReopen) {
validatorList.add(getBuyOfferCanReOpenValidator(buyOfferParam.getId()));
}
// 执行验证
return execute(validatorList);
}
};
}
上面的代码为具体的一个较验写法。validatorList 为一个校验列表
当执行validtor.validate();方法时,首先会将需要较验的一些“原子较验逻辑”封装成WebCheckValidtor对象,放入到validatorList 集合中,执行通用方法execute(validatorList);
protected ValidatorResult execute(LinkedList<WebCheckValidtor> validatorList) {
// 校验结果
ValidatorResult result = getValidatorResult();
// 校验器为空, 校验失败
if (validatorList == null || validatorList.isEmpty()) {
result.setSuccess(false);
result.setDefaultModel(BingResultCode.VALIDATOR_LIST_IS_EMPTY);
return result;
}
// 执行验证
for (WebCheckValidtor validator : validatorList) {
if (validator == null)
continue;
validator.validate();
if (!result.isSuccess()) {
break;
}
}
// 清空内容
threadLocal.remove();
return result;
}
该方法有以下关键步骤:
1.getValidatorResult()方法会定义一个对象存入 线程的附属变量中,并将对象(内存中的空间地址)返回给上文中的execute方法中的result 变量
protected ValidatorResult getValidatorResult() { ValidatorResult result = threadLocal.get(); if (result == null) { result = new ValidatorResult(true); threadLocal.set(result); } return result; }
2.for循环执行具体的原子逻辑,以下面代码为例(检查当前member是否存在)
protected WebCheckValidtor checkMemberExistValidator(final String memberId) { return new WebCheckValidtor() { public ValidatorResult validate() { Person person = memberLogic.getPersonByMemberId(memberId); ValidatorResult ret = getValidatorResult(); if (null == person) { ret.setSuccess(false); ret.setResultCode(BingResultCode.MEMBER_NOT_EXIST); } ret.setPerson(person); return ret; } }; }
通过getValidatorResult()方法获取当前的线程的附属变量,如果验证失败,则将失败信息存入到ret中,(ret与上文的result指向同一个堆空间),此时的返回值没有什么意义。
然后 if (!result.isSuccess()) break; 对当前执行完毕的校验结果作判断,如果为false则退出循环,清空线程变量的内容,返回结果对象,
直到Action类,
Result ret = validtor.validate(); if (!ret.isSuccess()) { context.put(ERROR_MESSAGE, ret.getResultCode().getMessage()); return; }
如果失败,则走失败分支,记录错误信息;否则执行正常操作。