近期做一个接口。接受外系统的报文,通过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 欢迎交流



通过Pojo对象 field 属性加注解实现格式校验,极大的降低代码量的更多相关文章

  1. 漫淡面向对象——POJO对象

    产品或者服务由数据存储和数据计算组成.pojo对象就是用于数据存储.一旦确定后,整个应用或者产品的数据来源就确定.比如一个页面或者功能需要使用什么数据就可以快速找到对应的对象或者通过对象的关系找出来. ...

  2. Hibernate三种状态;query查询;ResultTransformer转换为pojo对象;能够将query语句写在xml中;Criteria查询;ProjectionList总和/f分组等函数

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u010026901/article/details/24256091 Session操作过程中的po ...

  3. 使用java中的反射获得object对象的属性值

    知识点:使用java中的反射获得object对象的属性值 一:场景 这两天开发代码时,调用别人的后台接口,返回值为Object对象(json形式的),我想获得object中指定的属性值,没有对应的ge ...

  4. 一个注解搞定SpringBoot接口定制属性加解密

    前言 上个月公司另一个团队做的新项目上线后大体上运行稳定,但包括研发负责人在内的两个人在项目上线后立马就跳槽了,然后又交接给了我这个「垃圾回收人员」. 本周甲方另一个厂家的监控平台扫描到我们这个项目某 ...

  5. 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间

    [源码下载] 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间 作者:webabcd 介绍速战速决 之 PHP 动态地创 ...

  6. 【基本功】Java动态追踪技术探究 不重启JVM,替换掉已经加载的类?不重启JVM,获知运行时对象的属性

    https://mp.weixin.qq.com/s/_hSaI5yMvPTWxvFgl-UItA 小结: 1.根据Java的类加载机制,在同一个ClassLoader中,类是不允许重复的: 2.单例 ...

  7. 【java】java反射机制,动态获取对象的属性和对应的参数值,并属性按照字典序排序,Field.setAccessible()方法的说明【可用于微信支付 签名生成】

    方法1:通过get()方法获取属性值 package com.sxd.test.controller; public class FirstCa{ private Integer num; priva ...

  8. Django---CBV和FBV的使用,CBV的流程,给视图加装饰器,Request对象方法,属性和Response对象,form表单的上传

    Django---CBV和FBV的使用,CBV的流程,给视图加装饰器,Request请求对象方法,属性和Response响应对象,form表单的上传 一丶CBV和FBV       在Django中存 ...

  9. 使用XStream是实现XML与Java对象的转换(3)--注解

    六.使用注解(Annotation) 总是使用XStream对象的别名方法和注册转换器,会让人感到非常的乏味,又会产生很多重复性代码,于是我们可以使用注解的方式来配置要序列化的POJO对象. 1,最基 ...

随机推荐

  1. iOS-OAuth认证

    OAuth授权 OAuth授权分四步: 第一步,应用向服务提供方申请请求令牌(Request Token),服务提供方验证通过后将令牌返回.这个步骤由于涉及到应用帐号密码,在应用的服务端发起,所以这个 ...

  2. zabbix基于LNMP安装

    安装依赖 yum install pcre* #为了支持rewrite功能 yum install openssl openssl-devel yum install gcc make gd-deve ...

  3. 标准C程序设计七---51

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...

  4. 为什么linux下多线程程序如此消耗虚拟内存【转】

    转自:http://blog.csdn.net/chen19870707/article/details/43202679 权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[-] 探 ...

  5. 问题:Linux 输入任何命令都显示 -bash: fork: Cannot allocate memory

    应该是某个程序吃掉了所有的内存,只能重启

  6. (1)Unity3d界面、入门

    项目视图 层级视图 属性视图 场景视图 游戏视图 调整u3d整体界面布局 1.查看和移动视图 快捷键Q 2.沿轴方向位移 快捷键W 3.沿轴向旋转 快捷键E 4.沿轴向缩放 快捷键R 5.自由调节小大 ...

  7. Go -- FIFO类(缓存淘汰算法)(转)

    1 FIFO 1.1. 原理 按照“先进先出(First In,First Out)”的原理淘汰数据. 1.2. 实现 FIFO队列,具体实现如下: 1. 新访问的数据插入FIFO队列尾部,数据在FI ...

  8. linux查看 cpu及内存和硬盘使用情况的命令top

    使用时输入 top,退出时输入q http://www.cnblogs.com/ggjucheng/archive/2012/01/08/2316399.html 简介 top命令是Linux下常用的 ...

  9. editplus重新载入文档

    editplus重新载入文档 :document->reload

  10. hadoop常见错误

    hadoop常见错误集锦: 1.DataXceiver error processing WRITE_BLOCK operation ERROR org.apache.hadoop.hdfs.serv ...