这里的过滤器的作用主要是在业务逻辑里面判断,传递的参数是否有误,然后在实现类里面去判断具体的业务数据,执行流程和servlet的过滤器相类似,但是执行时机和作用大不相同,servlet的执行时机是在请求资源,在达到control之前去执行,通过执行链,我们的这个过滤器是在control里,代码如下.
先定义个Filter接口
里面的evidence是根据业务逻辑生成的pojo,其中result用于接受过滤的结果
public interface Filter {
void doFilter(Evidence evidence, Result result) throws RuleExecuteException;
}
Filter实现类(执行具体的业务逻辑)
public class IdCardCheckFilter implements Filter {
private static Logger logger = LoggerFactory.getLogger("investableEvidenceCheckLog");
private static final byte INVALID_ID_CARD_AUTH_CODE = 0;
@Resource
private UserInfoDao userInfoDao;
@Override
public void doFilter(Evidence evidence, Result result) throws RuleExecuteException {
InvestableEvidence investableEvidence = (InvestableEvidence) evidence;
InvestableResult investableResult = (InvestableResult) result;
if (investableEvidence.getIdCardAuth() == INVALID_ID_CARD_AUTH_CODE || investableEvidence.getIdCardAuth() == null) {
logger.info("check investableEvidence:{} error,idCard is invalid:{}!", investableEvidence, investableEvidence.getIdCardAuth());
investableResult.setCode(InvestableResultEnum.ID_CARD_AUTH_INVALID.getCode());
investableResult.setMsg(InvestableResultEnum.ID_CARD_AUTH_INVALID.getMsg());
return;
}
}
}
FilterChain接口
public interface FilterChain {
void doFilter(Evidence evidence, Result result) throws RuleExecuteException;
}
FilterChainImpl
这里他有个属性是filters的实现类,可以通过配置文件给他赋值,把具体的filter的实现类注入进来
public class FilterChainImpl implements FilterChain {
private static Logger logger = LoggerFactory.getLogger(FilterChainImpl.class);
private Collection<Filter> filters;
private int index;
@Override
public void doFilter(Evidence evidence, Result result) throws RuleExecuteException {
logger.debug("rule filters is empty,check filter conf===================ig!");
if (CollectionUtils.isEmpty(filters)) {
logger.debug("rule filters is empty,check filter config!");
return;
}
for (Filter filter : filters) {
if (filter == null) {
logger.error("filter:{} is null,check config!", ToStringBuilder.reflectionToString(filter));
}
try {
filter.doFilter(evidence, result);
} catch (Exception e) {
logger.error("filter:{} execute error!", ToStringBuilder.reflectionToString(filter));
throw new RuleExecuteException(filter.getClass().getName() + " execute error");
}
}
}
public void setFilters(Collection<Filter> filters) {
this.filters = filters;
}
}
配置文件<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<bean id="investCheckFilterChain" class="com.peanut.p2p.rule.filter.impl.FilterChainImpl" >
<property name="filters">
<list>
<ref bean="moneyCheckFilter"/>
<ref bean="idCardCheckFilter"/>
</list>
</property>
</bean>
<bean id="idCardCheckFilter" class="com.peanut.p2p.transaction.rule.filter.IdCardCheckFilter"/>
<bean id="moneyCheckFilter" class="com.peanut.p2p.transaction.rule.filter.MoneyCheckFilter"/>
</beans>
在filter实现类里面,给result赋值的时候用到了枚举,这种写法很少见.可以观赏下
public enum InvestableResultEnum {
USER_INFO_INVALID("用户信息不合法", (byte) 0),//未登录或者用户信息没有查到
REFUND_INVALID("用户输入金额不合法", (byte) 1),//用户输入金额不合法
MOBILE_AUTH_INVALID("用户手机号未认证", (byte) 2),
ID_CARD_AUTH_INVALID("用户身份证未认证", (byte) 3),
BANK_RELATIONSHIP_AUTH_INVALID("用户银行未绑定", (byte) 4),
PRODUCT_ID_INVALID("产品ID不合法", (byte) 5),
PRODUCT_TRANSFER_INFO_INVALID("不存在此债券转让信息", (byte) 6),
PRODUCT_TRANSFER_EXPIRED("此债券转让已过期", (byte) 7),
USER_ACCOUNT_NOT_EXIST("用户账号不存在", (byte) 8),
USER_ACCOUNT_NOT_ENOUGH("用户余额不足", (byte) 9),
PRICE_STOCK_NOT_EXIST("价格库存不存在", (byte) 10),
PRICE_STOCK_NOT_ENOUGH("剩余量已不足,请重新输入", (byte) 11),
PRODUCT_TRANSFER_NOT_START("此债券转让未开始", (byte) 12),
PRODUCT_TRANSFER_NEARLY_START("由于购买人数过多,稍后请再尝试购买", (byte) 13),
PRODUCT_TRANSFER_MINS("对不起,您输入的金额不是最小投资金额整数倍,请重新输入", (byte) 14),
PRODUCT_TRANSFER_MINS_S("对不起,您输入的金额不能少于最小投资金额,请重新输入", (byte) 15),
SYS_CHECK_ERROR("请稍后再试", (byte) 111),
SUCCESS("校验成功", (byte) 110);
private String msg;
private byte code;
InvestableResultEnum(String msg, byte code) {
this.msg = msg;
this.code = code;
}
public String getMsg() {
return msg;
}
public byte getCode() {
return code;
}
}
Spring注入配置文件
<import resource="classpath:beans/rule.xml"/>