请求发送者和接收者连接成一条链,一个对象处理完,交给下一位,沿着链传递请求,这就是责任链模式。
在使用前端给后端传入的数据前,都需要做校验,比如数据完整性校验等等。一个一个 if-else 写起来比较麻烦,请使用责任链模式优化代码编写体验。
工具类:
Mapx:
import java.util.HashMap;
public class Mapx<K, V> extends HashMap<K, V> {
public static Mapx init(String key, Object value) {
return new Mapx().set(key,value);
}
public Mapx<K, V> set(K key, V value){
this.put(key, value);
return this;
}
}
Setx:
import java.util.HashSet;
public class Setx extends HashSet {
public static Setx init(Object obj){
return new Setx().set(obj);
}
public Setx set(Object obj){
this.add(obj);
return this;
}
}
Res:REST接口返回格式生成器
import java.util.Map;
public class Res {
public static Map ok(String msg, int symbol, Object data) {
return Mapx.init("code",200)
.set("symbol",symbol)
.set("data",data)
.set("type","ok");
}
public static Map fail(String msg, int symbol, Object data) {
return Mapx.init("code",400)
.set("symbol",symbol)
.set("data",data)
.set("type","fail");
}
}
Checker:抽象处理者
import java.util.Map;
import java.util.Set;
public interface Checker {
public Checker hint(String hint);
public Checker symbol(int symbol);
public Checker ignore(Object ign);
public Map check();
public Checker next(Checker nextChecker);
}
CompleteChecker:完整性检查者
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class CompleteChecker implements Checker{
private Object suspicion;
private String hint;
private int symbol;
private Set ign;
private Checker nextChecker;
public CompleteChecker(Object suspicion) {
this.suspicion = suspicion;
}
@Override
public Checker hint(String hint) {
this.hint = hint;
return this;
}
@Override
public Checker symbol(int symbol) {
this.symbol = symbol;
return this;
}
@Override
public Map check() {
String result = this.is_complete(suspicion, ign);
if (result!=null){
Map data = Mapx.init("field", result);
return Res.fail(hint, symbol, data);
}
if (nextChecker!=null){
return nextChecker.check();
}
return null;
}
@Override
public Checker next(Checker nextChecker) {
this.nextChecker = nextChecker;
return nextChecker;
}
public CompleteChecker ignore(Object ign){
Set ignx = (Set) ign;
this.ign = ignx;
return this;
}
private String is_complete(Object obj, Set<String> ign){
if(obj==null){
return "Self";
}
if(ign==null){
ign = new HashSet<>();
}
Field[] fields = obj.getClass().getDeclaredFields();
Boolean rs = true;
for (Field field : fields) {
field.setAccessible(true);
Object fieldValue = null;
String fieldName = "";
Type fieldType = null;
try {
fieldValue = field.get(obj); //得到属性值
fieldType = field.getGenericType();//得到属性类型
fieldName = field.getName(); // 得到属性名
// System.out.println("属性类型:" + fieldType.getTypeName() + ",属性名:" + fieldName + ",属性值:" + fieldValue);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if(ign.contains(fieldName)){
// System.out.println(fieldName+" 属性忽略检测");
continue;
}
if (fieldValue == null || fieldValue.equals("")) { //只要有一个属性值不为null 就返回false 表示对象不为null
// System.out.println("检测的成员变量中有空值");
// System.out.println(fieldName + "为空");
// System.out.println(fieldName + ": " + fieldValue);
return fieldName;
}
// 如果成员是列表
if (fieldValue instanceof java.util.List) {
if (((List<?>) fieldValue).size()==0){
return fieldName;
}
}
}
return null;
}
}
Main:
public class Main {
public static void main(String[] args) {
User user = new User(
"小靳", "female", 20,
new User("父亲","male",50,
new User("爷爷", "male", 70, null))
);
Checker checker = new CompleteChecker(user)
.ignore(Setx.init("age")).hint("user不完整");
checker.next(new CompleteChecker(user.father))
.ignore(Setx.init("age")).hint("father不完整")
.next(new CompleteChecker(user.father.father))
.ignore(Setx.init("age")).hint("grandfather不完整");
System.out.println("检测结果: " + checker.check());
}
}
Output:
检测结果: {msg=grandfather不完整, symbol=0, code=400, data={field=father}, type=fail}
当然,我这个案例的代码实现存在漏洞,user.father为null的时候,user.father.father是取不到的。
优点:
缺点: