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是代码里的特殊标记,这些标记可以在编译.类加载.运行时被读取,并执行 ...
随机推荐
- pip 命令安装 rdbtools
命令 pip install tdbtools 如果出现类似如下错误 Could not fetch URL https://pypi.org/simple/redis/ 说明morning的pip ...
- SQLServer日常bug记录
问题1:如下图所示 原因分析:同时操作数据库中的两条数据引起的 解决方法:新建查询语句 delete 数据库名字.表名 where 引起错误的字段=引起错误的字段值
- 微服务架构 ------ 插曲 Mybatis逆向工程
1.首先是pom.xml, 我们需要引入需要的mvn插件 <?xml version="1.0" encoding="UTF-8"?> <pr ...
- 关于spring中请求返回值的json序列化/反序列化问题
https://cloud.tencent.com/developer/article/1381083 https://www.jianshu.com/p/db07543ffe0a 先留个坑
- Atlassian JIRA服务器模板注入漏洞复现(CVE-2019-11581)
0x00 漏洞描述 Atlassian Jira是澳大利亚Atlassian公司的一套缺陷跟踪管理系统.该系统主要用于对工作中各类问题.缺陷进行跟踪管理. Atlassian Jira Server和 ...
- B端产品需求文档怎么写?
B端,或者2B,一般指的是英文中的 to busniss,中文即面向企业的含义.与B端相对应的,是C端,或者2C,同样指的是英文中的 to customer,即面向消费者的意思.因此,人们平常所说的B ...
- 分布式session的解决方案
1.Nginx的ip_hash,对应tomcat的session,由tomcat保存 缺点:一旦tomcat单点挂机,session消失 2.session在tomcat之间复制, 缺点:保存全局se ...
- InvalidOperationException: Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's
InvalidOperationException: Operations that change non-concurrent collections must have exclusive acc ...
- 常用SQL语句分享
前言: 日常工作或学习过程中,我们可能会经常用到某些SQL,建议大家多多整理记录下这些常用的SQL,这样后续用到会方便很多.笔者在工作及学习过程中也整理了下个人常用的SQL,现在分享给你!可能有些S ...
- 0x02 Python logging模块利用配置加载logger
目录 logging模块利用配置加载logger 方式一模板:logging.config.dictConfig(config_dict) logging模块利用配置加载logger logging. ...