java利用注解及反射做通用的入参校验
一、原理:
1、做一个field注解,注解有两个参数:是否必填、toString之后的最大长度
2、对某个request类(或基类),使用注解标记某个字段的校验详情
3、通用的static方法,利用反射获取属性的值,并做校验。不通过则抛出特定的异常
二、上代码:
异常类:
package com.test; /**
* 基础异常
* @author zyydd
* @date 2019/1/24 10:33
* @version 1.0.0
**/
public class BaseException extends RuntimeException { /** 异常码 */
private String code;
/** 异常描述 */
private String desc; public BaseException(){ } public String getCode() {
return code;
} private void setCode(String code) {
this.code = code;
} public String getDesc() {
return desc;
} private void setDesc(String desc) {
this.desc = desc;
} public BaseException(String code, String desc) {
this(code, desc, new Throwable(desc));
} public BaseException(String code, String desc, Throwable canse) {
super(new StringBuilder().append("code=").append(code).append(", desc=").append(desc).toString(), canse);
this.setCode(code);
this.setDesc(desc);
} @Override
public String toString() {
return new StringBuilder().append(getClass().getName())
.append("{code=").append(this.getCode())
.append(", desc=").append(this.getDesc())
.append("}").toString();
}
}
测试的request类:
package com.test; /**
* @author zyydd
* @date 2019/6/13 18:29
*/
public class TestChildRequest {
/**
* name
*/
@ParameterAttr(isNecessary = true, lengthLimit = 10)
private String name; /**
* pin
*/
@ParameterAttr(lengthLimit = 15)
private String address; @ParameterAttr(isNecessary = true)
private String school; private String other; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getAddress() {
return address;
} public void setAddress(String address) {
this.address = address;
} public String getSchool() {
return school;
} public void setSchool(String school) {
this.school = school;
} public String getOther() {
return other;
} public void setOther(String other) {
this.other = other;
}
}
field校验注解类:
package com.test; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* @author zyydd
* @date 2019/6/13 16:52
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ParameterAttr {
/**
* 是否必须,默认不必须
*
* @return
*/
boolean isNecessary() default false; /**
* 属性toSring之后,最大长度
*
* @return
*/
int lengthLimit() default 0; }
通用校验工具类及main测试方法:
package com.test; import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; /**
* @author zyydd
* @date 2019/6/13 17:02
*/
public class ParameterCheckUtils {
private static Logger logger = LoggerFactory.getLogger(ParameterCheckUtils.class); public static void commonCheck(Object obj) throws IllegalAccessException {
if (obj == null) {
logger.error("obj can not be null!");
throw new BaseException("9999", "obj can not be null!");
} List<Field> fieldList = new ArrayList<Field>();
Class clazz = obj.getClass();
while (!Object.class.equals(clazz)) {
fieldList.addAll(Arrays.asList(clazz.getDeclaredFields()));
clazz = clazz.getSuperclass();
}
for (Field field : fieldList) {
field.setAccessible(true);
ParameterAttr attr = field.getAnnotation(ParameterAttr.class);
if (attr == null) {
continue;
}
Object paramObj = field.get(obj);
if (attr.isNecessary()) {
if (paramObj == null || StringUtils.isBlank(paramObj.toString())) {
logger.error("class={} field={} can not be null!", obj.getClass().getName(), field.getName());
throw new BaseException("9998", "field=" + field.getName() + " can not be null!");
}
}
if (attr.lengthLimit() > 0 && paramObj != null && StringUtils.isNotBlank(paramObj.toString())) {
if (paramObj.toString().length() > attr.lengthLimit()) {
logger.error("class={} field={} length is too long! limit={} but length={}", obj.getClass().getName(), field.getName(), attr.lengthLimit(), paramObj.toString().length());
throw new BaseException("9997", "field=" + field.getName() + " length is too long!");
}
}
}
logger.info("commonCheck success!");
} public static void main(String[] args) throws IllegalAccessException {
//正常数据
TestChildRequest request1 = new TestChildRequest();
request1.setName("王钢蛋");
request1.setAddress("aabbccddeeaabbc");
request1.setSchool("北京市智障二中");
ParameterCheckUtils.commonCheck(request1); //为空数据
try {
ParameterCheckUtils.commonCheck(null);
} catch (Exception e) {
logger.error("error1 ", e); }
//必填没传的数据
try {
TestChildRequest request2 = new TestChildRequest();
request2.setName("王钢蛋");
request2.setAddress("aabbccddeeaabbc");
ParameterCheckUtils.commonCheck(request2);
} catch (Exception e) {
logger.error("error2 ", e);
} //字段超长的数据
try {
TestChildRequest request3 = new TestChildRequest();
request3.setName("王钢蛋");
request3.setAddress("aabbccddeeaabbcc");
request3.setSchool("北京市智障二中");
ParameterCheckUtils.commonCheck(request3);
} catch (Exception e) {
logger.error("error3 ", e);
}
} }
执行结果:

java利用注解及反射做通用的入参校验的更多相关文章
- 【Java】利用注解和反射实现一个"低配版"的依赖注入
在Spring中,我们可以通过 @Autowired注解的方式为一个方法中注入参数,那么这种方法背后到底发生了什么呢,这篇文章将讲述如何用Java的注解和反射实现一个“低配版”的依赖注入. 下面是我们 ...
- Java基于注解和反射导入导出Excel
代码地址如下:http://www.demodashi.com/demo/11995.html 1. 构建项目 使用Spring Boot快速构建一个Web工程,并导入与操作Excel相关的POI包以 ...
- 使用Java元注解和反射实现简单MVC框架
Springmvc的核心是DispatcherServlet来进行各种请求的拦截,进而进行后续的各种转发处理.流程图如下: 说明:客户端发出一个http请求给web服务器,web服务器对http请求进 ...
- Java之注解与反射
Java之注解与反射 注解(Annotation)简介 注解(Annotation)是从JDK5.0引入的新技术 Annotation作用:注解(Annotation)可以被其他程序如编译器等读取 A ...
- java自定义注解与反射
java注解与反射一.Java中提供了四种元注解,专门负责注解其他的注解,分别如下 1.@Retention元注解,表示需要在什么级别保存该注释信息(生命周期).可选的RetentionPoicy参数 ...
- java 利用注解实现BaseDao 增删查改
第一步,编写两个注解类,用于表明实体类对应的表名及字段. TableInfo.java 此注解用于标注表名及主键名 import static java.lang.annotation.Element ...
- postman中用当前时间戳做请求的入参
用postman做接口测试的,有些接口需要带上当前时间的时间戳作为请求的入参,postman支持这种功能吗? 答案是肯定的. 文中有使用时间戳的两种方法和postman常用的预定义变量. 例子中接口的 ...
- Java注解(Annotation)用法:利用注解和反射机制指定列名导出数据库数据
闲来没事,想了一个应用的例子:用java如何把数据库的数据根据我们指定的某几列,如第2列,第4列,第6列导出来到Excel里? 写代码也是为了应用的,写好的代码更重要的是在于思考.我自己思考了这个示例 ...
- Java基础--注解、反射
一.注解(Annotation) 1.什么是注解? 从JDK5开始,Java增加了Annotation(注解),Annotation是代码里的特殊标记,这些标记可以在编译.类加载.运行时被读取,并执行 ...
随机推荐
- C# vb .NET读取识别条形码线性条码ISBN
ISBN是比较常见的条形码编码规则类型的一种.如何在C#,vb等.NET平台语言里实现快速准确读取该类型条形码呢?答案是使用SharpBarcode! SharpBarcode是C#快速高效.准确的条 ...
- apktool 反编译 回编译
下载apktool 安装好Java环境 拷贝apk 拷贝game.apk到当前文件夹.apk随便指定 反编译 反编译完成.生成game目录 game目录内容 回编译 回编译完成.生成build和dis ...
- Spring Cloud 微服务实战笔记
Spring Cloud 微服务实战笔记 微服务知识 传统开发所有业务逻辑都在一个应用中, 开发,测试,部署随着需求增加会不断为单个项目增加不同业务模块:前端展现也不局限于html视图模板的形式,后端 ...
- CDH报错:PersistenceException: [PersistenceUnit: cmf.server] Unable to build EntityManagerFactory
1.在启动CDH中master的服务cloudera-scm-server start并立刻挂掉了,提示如下错误 org.springframework.beans.factory.BeanCreat ...
- PHP 格式化显示时间 date() 函数【转】
date() 函数 功能:用于格式化时间,返回一个字符串. 语法:string date( string format [, int timestamp] ),其中参数 format 表示时间格式化 ...
- 黑白之间的FastFlux
DNS请求 通常我们对一个域名进行DNS请求,尤其是A记录,一般在一段时间内是不变的,其结果的异同也就是可能因地域而得到不同的结果.当然这个结果可能是个集合,也可能是一个IP地址.因为我们要考虑到CD ...
- angular6 监听url查询参数变化刷新页面
快照snapshot取到的参数是组件第一次渲染时候的参数,当我们在页面中需要根据不同的url查询参数显示不同的内容时,快照就不能满足我们的需要了,这时候就要用ActivatedRoute服务的quer ...
- php-fpm编译安装脚本
PHP是开源.轻量级.高效的开发语言,特别适合web项目开发,在中小型互联网公司中常用于开发web后端.PHP常与Nginx及MySQL数据库结合,搭建LNMP环境.以下为centos7系统下ph ...
- javascript打开窗口
项目中javascript代码,早期使用了只有ie支持的方法:Window createPopup() 方法 那个时候是2009年,而现在已经是2019-12-11了.如何改造这个早期的代码呢? 找到 ...
- centos curl安装
二.安装 1.解压 下载到的压缩包为curl-7.51.0.tar.gz,使用命令 tar -zxvf curl-7.51.0.tar.gz 解压. 2.进入解压出的目录curl-7.51.0, ...