通过Pojo对象 field 属性加注解实现格式校验,极大的降低代码量
近期做一个接口。接受外系统的报文,通过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 属性加注解实现格式校验,极大的降低代码量的更多相关文章
- 漫淡面向对象——POJO对象
产品或者服务由数据存储和数据计算组成.pojo对象就是用于数据存储.一旦确定后,整个应用或者产品的数据来源就确定.比如一个页面或者功能需要使用什么数据就可以快速找到对应的对象或者通过对象的关系找出来. ...
- Hibernate三种状态;query查询;ResultTransformer转换为pojo对象;能够将query语句写在xml中;Criteria查询;ProjectionList总和/f分组等函数
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u010026901/article/details/24256091 Session操作过程中的po ...
- 使用java中的反射获得object对象的属性值
知识点:使用java中的反射获得object对象的属性值 一:场景 这两天开发代码时,调用别人的后台接口,返回值为Object对象(json形式的),我想获得object中指定的属性值,没有对应的ge ...
- 一个注解搞定SpringBoot接口定制属性加解密
前言 上个月公司另一个团队做的新项目上线后大体上运行稳定,但包括研发负责人在内的两个人在项目上线后立马就跳槽了,然后又交接给了我这个「垃圾回收人员」. 本周甲方另一个厂家的监控平台扫描到我们这个项目某 ...
- 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间
[源码下载] 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间 作者:webabcd 介绍速战速决 之 PHP 动态地创 ...
- 【基本功】Java动态追踪技术探究 不重启JVM,替换掉已经加载的类?不重启JVM,获知运行时对象的属性
https://mp.weixin.qq.com/s/_hSaI5yMvPTWxvFgl-UItA 小结: 1.根据Java的类加载机制,在同一个ClassLoader中,类是不允许重复的: 2.单例 ...
- 【java】java反射机制,动态获取对象的属性和对应的参数值,并属性按照字典序排序,Field.setAccessible()方法的说明【可用于微信支付 签名生成】
方法1:通过get()方法获取属性值 package com.sxd.test.controller; public class FirstCa{ private Integer num; priva ...
- Django---CBV和FBV的使用,CBV的流程,给视图加装饰器,Request对象方法,属性和Response对象,form表单的上传
Django---CBV和FBV的使用,CBV的流程,给视图加装饰器,Request请求对象方法,属性和Response响应对象,form表单的上传 一丶CBV和FBV 在Django中存 ...
- 使用XStream是实现XML与Java对象的转换(3)--注解
六.使用注解(Annotation) 总是使用XStream对象的别名方法和注册转换器,会让人感到非常的乏味,又会产生很多重复性代码,于是我们可以使用注解的方式来配置要序列化的POJO对象. 1,最基 ...
随机推荐
- Qtree
Qtree Ⅰ 题意:https://vjudge.net/problem/SPOJ-QTREE 带修路径查询最大边权 sol :树链剖分,之后每条重链就是一个连续的区间,拿线段树维护即可 简单讲讲 ...
- Django模板遍历字典的方法
使用Python + Django做Web开发时,有时需要在view中传递一个字典给模板(template),如何在模板中遍历字典呢? 下面介绍两种方法: views.py代码如下: dicts = ...
- HDU 2594 kmp算法变形
Simpsons’ Hidden Talents Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java ...
- Linq技巧1——关联实体查询排序
假如想查询拖欠按揭超过30天的银行帐号,同时查询出他们的单据,并且需要按照单据日期进行排序,这样可以首先看到最近的单据,方便找出问题. 大多数人都知道EF可以使用Include()热加载关系实体,例如 ...
- node起始——安装并且新建一个node项目
1.安装nodejs和npm http://nodejs.cn/ 2.设置环境变量,安装到那里就在那里配置. 3.express开发框架安装 //命令行输入命令 npm install -g expr ...
- linux内核中打印栈回溯信息 - dump_stack()函数分析【转】
转自:http://blog.csdn.net/jasonchen_gbd/article/details/45585133 版权声明:本文为博主原创文章,转载请附上原博链接. 目录(?)[-] ...
- zoj 2760(网络流+floyed)
How Many Shortest Path Time Limit: 10 Seconds Memory Limit: 32768 KB Given a weighted directed ...
- delphi中关于时间差的实例
http://www.cnblogs.com/rogee/archive/2010/09/20/1832035.html 很多时候要用到相差多少天,多少周,多少秒,查了一下资料,整理如下: 首先 us ...
- (41)C#异步编程
VS2010是经常阻塞UI线程的应用程序之一.例如用vs2010打开一个包含数百个项目的解决方案,可以要等待很长时间(感觉像卡死),自从vs2012情况得到了改善,项目在后台进行了异步加载. 一.同步 ...
- 2017 ACM-ICPC 北京区域赛记录
------------------------------------------------------------------------------ 出发日 拖着一个大箱子走是真的累. 下午三 ...