通过Pojo对象 field 属性加注解实现格式校验,极大的减少代码量

来源:互联网 发布:大数据分析书籍 编辑:程序博客网 时间:2024/06/05 14:55

最近做一个接口,接受外系统的报文,通过XStream转换成java对象以后,需要对其中的字段做格式校验。要求如下:

传统的方式是硬编码校验,但是对于field很多的情况,代码量暴增。容易出错。

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 欢迎交流





0 0
原创粉丝点击