近期做一个接口。接受外系统的报文,通过XStream转换成java对象以后。须要对当中的字段做格式校验。
要求例如以下:
传统的方式是硬编码校验。可是对于field非常多的情况。代码量暴增。easy出错。
String storeCode = uHeader.getStoreCode(); if (StringUtils.isNotBlank(storeCode)) { ParamsUtil.getInstance().checkStrParam(result, storeCode, "抬头-參考订单门店号[storeCode]", LSPConstants.NUM_TEN); if (!result.isSuccess()) { return result; } } String routing = uHeader.getRouting(); if (StringUtils.isNotBlank(routing)) { ParamsUtil.getInstance().checkStrParam(result, routing, "抬头-路线[routing]", LSPConstants.NUM_SIX); if (!result.isSuccess()) { return result; } } String areaDeliBusSysId = uHeader.getAreaDeliBusSysId(); if (StringUtils.isNotBlank(areaDeliBusSysId)) { ParamsUtil.getInstance().checkStrParam(result, areaDeliBusSysId, "抬头-辖区内配送班车系统编号 [areaDeliBusSysId]", LSPConstants.NUM_TEN); if (!result.isSuccess()) { return result; } } String transBusSysId = uHeader.getTransBusSysId(); if (StringUtils.isNotBlank(transBusSysId)) { ParamsUtil.getInstance().checkStrParam(result, transBusSysId, "抬头-联运班车系统编号[transBusSysId]", LSPConstants.NUM_TEN); if (!result.isSuccess()) { return result; } } String nostopBusSysId = uHeader.getNostopBusSysId(); if (StringUtils.isNotBlank(nostopBusSysId)) { ParamsUtil.getInstance().checkStrParam(result, nostopBusSysId, "抬头-直达班车班车编号[nostopBusSysId]", LSPConstants.NUM_TEN); if (!result.isSuccess()) { return result; } } String speBusSysId = uHeader.getSpeBusSysId(); if (StringUtils.isNotBlank(speBusSysId)) { ParamsUtil.getInstance().checkStrParam(result, speBusSysId, "抬头-穿梭班车系统编号1[speBusSysId]", LSPConstants.NUM_TEN); if (!result.isSuccess()) { return result; } }
而我更希望的方式是通过对字段添加注解,由系统自己主动校验,如:
Pojo OmsTaskHead.java:
public class OmsTaskHead { @FieldNote(name = "參考订单门店号", type = FvEnum.STRING, regex = Regexs.letterAndDigit, isNullAble = true, length = 10) private String storeCode; // 參考订单门店号 @FieldNote(name = "路线", type = FvEnum.STRING, regex = Regexs.letterAndDigit, length = 6) private String routing; // 路线 @FieldNote(name = "辖区内配送班车系统编号", type = FvEnum.STRING, regex = Regexs.letterAndDigit, length = 10) private String areaDeliBusSysId; // 辖区内配送班车系统编号 @FieldNote(name = "联运班车系统编号", type = FvEnum.STRING, regex = Regexs.letterAndDigit, length = 10) private String transBusSysId; // 联运班车系统编号 @FieldNote(name = "直达班车班车编号", type = FvEnum.STRING, regex = Regexs.letterAndDigit, length = 10) private String nostopBusSysId; // 直达班车班车编号 @FieldNote(name = "穿梭班车系统编号1", type = FvEnum.STRING, regex = Regexs.letterAndDigit, length = 10) private String speBusSysId; // 穿梭班车系统编号1 @FieldNote(name = "联运班车发车日期", type = FvEnum.DATE_STR, regex = Regexs.yyyyMMdd, length = 8) private String transBusDate; // 联运班车发车日期 @FieldNote(name = "辖区班车发车日期", type = FvEnum.DATE_STR, regex = Regexs.yyyyMMdd, length = 8) private String areaDeliBusDate; // 辖区班车发车日期 @FieldNote(name = "直达班车发车日期", type = FvEnum.DATE_STR, regex = Regexs.yyyyMMdd, length = 8) private String nonstopBusDate; // 直达班车发车日期 //getter and setter methods }
自己定义注解 FieldNote.java:
package com.validate.intf; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import com.validate.holder.FvEnum; @Target({ ElementType.FIELD }) @Retention(RetentionPolicy.RUNTIME) public @interface FieldNote { /** * 名称 * @return */ String name(); /** * 类型 * @return */ FvEnum type(); /** * 能否够为空 * @return */ boolean isNullAble() default true; /** * 格式,能够是正则,默觉得空字符串 * @return */ String regex() default ""; /** * 长度(String) * @return */ int length() default -1; }
FvEnum.java(field validator enum) 字段校验方法集合。定义了不同类型field的校验方式:
package com.validate.holder; import com.validate.ResultVO; import com.validate.intf.FieldNote; import com.validate.intf.IValidator; /** * @author 15041965 2015-06-09 * */ public enum FvEnum { /* * CHAR, BOOL, INT, LONG, DOUBLE, FLOAT, */ DATE_STR(FieldValidatorHolder.DATE_STR), STRING(FieldValidatorHolder.STRING); @SuppressWarnings("rawtypes") private FvEnum(IValidator validator) { this.validator = validator; } @SuppressWarnings("rawtypes") private IValidator validator; @SuppressWarnings("unchecked") public <T> ResultVO validate(FieldNote fn,String fieldName, T fieldVal, ResultVO resultVO) { return validator.validate(fn,fieldName,fieldVal, resultVO); } }IValidator.java:
package com.validate.intf; import com.validate.ResultVO; /** * @author 15041965 2015-06-09 * */ public interface IValidator<T> { ResultVO validate(FieldNote fv,String fieldName,T fieldVal,ResultVO resultVO); }
ResultVO.java 校验结果载体:
package com.validate; import java.util.Collection; import java.util.HashSet; import java.util.Set; /** * 方法运行 结果 封装对象 * */ public class ResultVO { private boolean success = true;// 返回标识 private Set<String> errorCodes; // 错误消息代码 public ResultVO() { } public boolean isSuccess() { return success; } public void setSuccess(boolean success) { this.success = success; } public Set<String> getErrorCodes() { if (null == errorCodes) { errorCodes = new HashSet<String>(); } return errorCodes; } public void addError(String errorCode) { if (errorCode == null || "".equals(errorCode.trim())) { return; } if (!getErrorCodes().contains(errorCode)) { getErrorCodes().add(errorCode); } success = false; } public void addErrors(Collection<String> errors) { getErrorCodes().addAll(errors); success = false; } public String getErrorStr() { String str = errorCodes.toString(); return str.substring(1, str.length() - 1); } }
FieldValidatorHolder.java 和 FvEnum.java相应。是FvEnum.java里面各校验方式的详细实现持有类:
package com.validate.holder; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import org.springframework.util.StringUtils; import com.validate.ResultVO; import com.validate.intf.FieldNote; import com.validate.intf.IValidator; /** * @author 15041965 2015-06-09 * */ public class FieldValidatorHolder { public static final IValidator<String> STRING = newStringVal(); public static final IValidator<String> DATE_STR = new IValidator<String>() { public ResultVO validate(FieldNote fv, String fieldName, String fieldVal, ResultVO resultVO) { resultVO = checkNullAndLen(fv, fieldName, fieldVal, resultVO); if (!resultVO.isSuccess()) { return resultVO; } if (!StringUtils.isEmpty(fieldVal) && !StringUtils.isEmpty(fv.regex())) { if (!validateDate(fieldVal, fv.regex())) { resultVO.addError(fv.name() + "[" + fieldName + "]值[" + fieldVal + "]日期不合法或不能匹配格式 " + fv.regex()); return resultVO; } } return resultVO; } }; private static IValidator<String> newStringVal() { IValidator<String> validator = new IValidator<String>() { public ResultVO validate(FieldNote fv, String fieldName, String fieldVal, ResultVO resultVO) { resultVO = checkNullAndLen(fv, fieldName, fieldVal, resultVO); if (!resultVO.isSuccess()) { return resultVO; } if (!StringUtils.isEmpty(fieldVal) && !StringUtils.isEmpty(fv.regex()) && !fieldVal.matches(fv.regex())) { resultVO.addError(fv.name() + "[" + fieldName + "]值[" + fieldVal + "]不能匹配格式 " + fv.regex() + " "); return resultVO; } return resultVO; } }; return validator; } protected static ResultVO checkNullAndLen(FieldNote fv, String fieldName, String fieldVal, ResultVO resultVO) { if (StringUtils.isEmpty(fieldVal)) { if (!fv.isNullAble()) { resultVO.addError(fv.name() + "[" + fieldName + "]为空!"); } return resultVO; } if (fv.length() > 0 && (fieldVal.length() > fv.length())) { resultVO.addError(fv.name() + "[" + fieldName + "]长度(" + fieldVal.length() + ")超过限制(" + fv.length() + ")"); return resultVO; } return resultVO; } public static boolean validateDate(String dateStr, String pattern) { try { SimpleDateFormat dateFormat = new SimpleDateFormat(pattern); Date date = dateFormat.parse(dateStr); String pStr = dateFormat.format(date); return pStr.equals(dateStr); } catch (ParseException e) { return false; } } }
測试Main方法:
public static void main(String[] args) { OmsTaskHead head = new OmsTaskHead(); head.setRouting("555555"); head.setAreaDeliBusSysId("busiId1234"); head.setNostopBusSysId("not010101"); head.setSpeBusSysId("busId0101"); head.setTransBusSysId("trans0909"); head.setAreaDeliBusDate("20150640"); head.setNonstopBusDate("20150610"); head.setStoreCode("20150610"); head.setTransBusDate("20150610"); ResultVO resultVO = ObjFieldValUtil.validate(head); if(resultVO.isSuccess()){ System.out.println("校验成功!"); } else { System.out.println(resultVO.getErrorStr()); } }
执行结果:
这样是不是非常方便,qq:1773240270 欢迎交流