一、原理:

  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利用注解及反射做通用的入参校验的更多相关文章

  1. 【Java】利用注解和反射实现一个"低配版"的依赖注入

    在Spring中,我们可以通过 @Autowired注解的方式为一个方法中注入参数,那么这种方法背后到底发生了什么呢,这篇文章将讲述如何用Java的注解和反射实现一个“低配版”的依赖注入. 下面是我们 ...

  2. Java基于注解和反射导入导出Excel

    代码地址如下:http://www.demodashi.com/demo/11995.html 1. 构建项目 使用Spring Boot快速构建一个Web工程,并导入与操作Excel相关的POI包以 ...

  3. 使用Java元注解和反射实现简单MVC框架

    Springmvc的核心是DispatcherServlet来进行各种请求的拦截,进而进行后续的各种转发处理.流程图如下: 说明:客户端发出一个http请求给web服务器,web服务器对http请求进 ...

  4. Java之注解与反射

    Java之注解与反射 注解(Annotation)简介 注解(Annotation)是从JDK5.0引入的新技术 Annotation作用:注解(Annotation)可以被其他程序如编译器等读取 A ...

  5. java自定义注解与反射

    java注解与反射一.Java中提供了四种元注解,专门负责注解其他的注解,分别如下 1.@Retention元注解,表示需要在什么级别保存该注释信息(生命周期).可选的RetentionPoicy参数 ...

  6. java 利用注解实现BaseDao 增删查改

    第一步,编写两个注解类,用于表明实体类对应的表名及字段. TableInfo.java 此注解用于标注表名及主键名 import static java.lang.annotation.Element ...

  7. postman中用当前时间戳做请求的入参

    用postman做接口测试的,有些接口需要带上当前时间的时间戳作为请求的入参,postman支持这种功能吗? 答案是肯定的. 文中有使用时间戳的两种方法和postman常用的预定义变量. 例子中接口的 ...

  8. Java注解(Annotation)用法:利用注解和反射机制指定列名导出数据库数据

    闲来没事,想了一个应用的例子:用java如何把数据库的数据根据我们指定的某几列,如第2列,第4列,第6列导出来到Excel里? 写代码也是为了应用的,写好的代码更重要的是在于思考.我自己思考了这个示例 ...

  9. Java基础--注解、反射

    一.注解(Annotation) 1.什么是注解? 从JDK5开始,Java增加了Annotation(注解),Annotation是代码里的特殊标记,这些标记可以在编译.类加载.运行时被读取,并执行 ...

随机推荐

  1. Regex 常见语法

    常用元字符 . 匹配除换行符以外的任意字符. \w 匹配字母或数字或下划线或汉字.\W 匹配任意不是字母,数字,下划线,汉字的字符. \s 匹配任意的空白符.\S 匹配任意不是空白符的字符.等价于 [ ...

  2. Oracle数据库触发器

    第一次写触发器,浪费了一个小时,少了一个;编译不通过 当A表有更新或插入数据时,则触发器执行向B表插入对应条件的数据1 CREATE OR REPLACE TRIGGER Test -- 触发器名称 ...

  3. QQ互联,填写回调时注意事项

    今天在做QQ登录接口的时候,填写回调地址的时候,竟然出现了诡异的事情. 我的回调地址我直接填的域名,也申请通过了.但是在做开发地时候,一直提示这蛋疼的  redirect uri is illegal ...

  4. Mac 下安装 jdk

    1.安装jdk 我们是需要java环境的- 到oracle官网下载se: Java SE Development Kit 8 Downloads https://www.oracle.com/tech ...

  5. SpringJDBC源码解析

    读完本篇文章需要很长很长时间.... 传统JDBC 相信大家对传统的jdbc已经很熟悉了,无非就是下面这个流程 1234567891011 //1.加载驱动程序Class.forName(" ...

  6. Gin-Go学习笔记八:Gin-Web框架 常用的包

    常用的包 1>     在java,.net,php,node.js等语言常常会使用到包的概念.包的使用,可以加快项目的进度的开发,以及更好的实现项目的效果.我在网上查到了包的作用如下: 1.包 ...

  7. Git的下载安装

    下载地址:https://git-scm.com/download/win 命令: git add ...  ---将资源放到缓存区域 git commit  -m "提交说明"  ...

  8. 集成学习 - Bagging

    认识 Bagging 的全称为 (BootStrap Aggregation), 嗯, 咋翻译比较直观一点呢, 就有放回抽样 模型训练? 算了, 就这样吧, 它的Paper是这样的: Algorith ...

  9. Django框架(十二)-- Djang与Ajax

    一.什么是Ajax AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”.即使用Javascript语言与服务器进行异步交互,传 ...

  10. HDP 3.1.0 集成 Sqoop2

    HDP 3.1.0 集成 Sqoop2 本文原始地址:https://sitoi.cn/posts/65261.html 环境 由三台主机组成的 HDP 3.1.0 集群 配置好时间同步 步骤 下载 ...