自定注解验证请求报文
在做接口时需要验证接口报文,由于接口字段太多,准备使用注解验证,由于项目适用的jdk1.6,框架比较老,打算用自定义注解验证报文,在网上搜索了好几个相关博文,并不完全适用。于是自己学习着写了一下,用来验证接口报文是否符合要求,主要有:非空、长度验证。
本文的目的:
1、记录学习笔记
2、本人也是初学自定义注解,如果哪位大佬发现有不对或需要改进的地方,还望能指点一二,小弟不胜感激!
JDK版本:jdk1.6
1、创建注解类 Validation
package com.core.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER,ElementType.TYPE})
public @interface Validation {
// 是否可空,默认为非空
boolean isNull() default false;
/*提示信息*/
String description() default "";
/*最大长度*/
int maxLength() default 0;
/*最小长度*/
int minLength() default 0;
String maxValue() default "";
String minValue() default "";
}
@Target指定注解在那些java元素上使用。
public enum ElementType {
/** 类,接口(包括注解类型)或枚举的声明 */
TYPE,
/** 属性的声明 */
FIELD,
/** 方法的声明 */
METHOD,
/** 方法形式参数声明 */
PARAMETER,
/** 构造方法的声明 */
CONSTRUCTOR,
/** 局部变量声明 */
LOCAL_VARIABLE,
/** 注解类型声明 */
ANNOTATION_TYPE,
/** 包的声明 */
PACKAGE
}
@Retention注解,翻译为持久力、保持力。即用来修饰自定义注解的生命力。
2、创建验证工具类 ValidateUtil
package com.core.utils;
import com.core.annotation.Validation;
import org.apache.commons.lang.StringUtils;
import java.lang.reflect.Field;
public class ValidateUtil {
private static Validation validate;
public ValidateUtil() {
super();
}
/**
* 验证对象属性值
*
* @param object
* @throws Exception
*/
public static void valid(Object object) throws Exception {
//获取object的类型
Class<? extends Object> clazz = object.getClass();
//获取该类型声明的成员
Field[] fields = clazz.getDeclaredFields();
//遍历属性
for (Field field : fields) {
//对于private私有化的成员变量,通过setAccessible来修改器访问权限
field.setAccessible(true);
validate(field, object);
//重新设置会私有权限
field.setAccessible(false);
}
}
/**
* 验证属性值
*
* @param field
* @param object
* @throws Exception
*/
public static void validate(Field field, Object object) throws Exception {
String description;
//获取对象的注解信息,检查是否有Validation注解
validate = field.getAnnotation(Validation.class);
if (validate == null) {
return;
}
// 遍历数组获取元素验证
if (field.getType().isArray()) {
Object[] objects = (Object[]) field.get(object);
Class<?> aClass;
Field[] declaredFields;
for (Object obj : objects) {
aClass = obj.getClass();
declaredFields = aClass.getDeclaredFields();
for (Field field1 : declaredFields) {
field1.setAccessible(true);
// 这里产生回调
validate(field1, obj);
field1.setAccessible(false);
}
}
} else {
Object value = field.get(object);
if (!validate.isNull() && (StringUtils.isBlank(value.toString()))) {
throw new Exception(returnMessage(validate, field, "不能为空"));
}
if (value.toString().length() > validate.maxLength() && validate.maxLength() != 0) {
throw new Exception(returnMessage(validate, field, "长度不能超过" + validate.maxLength()));
}
if (value.toString().length() < validate.minLength() && validate.minLength() != 0) {
throw new Exception(returnMessage(validate, field, "长度不能小于" + validate.minLength()));
}
}
}
/**
* 返回验证信息
* (如果validation有值则返回validation,否则返回message)
* @param validation 自定义信息
* @param field
* @param message 提示信息
* @return
*/
private static String returnMessage(Validation validation, Field field, String message) {
String returnStr = "";
String description = validation.description();
if (StringUtils.isNotBlank(description)) {
returnStr = description;
} else {
returnStr = field.getName() + message;
}
return returnStr;
}
}
3、测试
**使用方法:在需要验证的实体类上添加注释 @Validation ,在属性上添加注释 **
**1、创建测试DTO(TestDto、TestDto_r) **
package com.dto;
import com.core.annotation.Validation;
/**
* 测试实体类
*/
@Validation
public class TestDto {
@Validation(maxLength = 3,description = "不能为空,最大长度为3位!")
private String id;
@Validation
private String to;
@Validation
private TestDto_r testDto_r;
@Validation
private TestDto_r[] testDto_rs;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public TestDto_r getTestDto_r() {
return testDto_r;
}
public void setTestDto_r(TestDto_r testDto_r) {
this.testDto_r = testDto_r;
}
public TestDto_r[] getTestDto_rs() {
return testDto_rs;
}
public void setTestDto_rs(TestDto_r[] testDto_rs) {
this.testDto_rs = testDto_rs;
}
}
package com.dto;
import com.core.annotation.Validation;
@Validation
public class TestDto_r {
@Validation
private String r_id;
@Validation
private String r_to;
public String getR_id() {
return r_id;
}
public void setR_id(String r_id) {
this.r_id = r_id;
}
public String getR_to() {
return r_to;
}
public void setR_to(String r_to) {
this.r_to = r_to;
}
}
**2、创建测试类Test **
使用 com.google.gson.Gson 将json报文转为对象,使用工具类进行验证。
package com.dto;
import com.google.gson.Gson;
import com.core.annotation.Validation;
import com.core.utils.ValidateUtil;
public class Test {
public static void main(String[] args) {
try {
String requestBody = "{\"id\":\"0\",\"to\":\"test\",\"testDto_r\":{\"r_id\":\"1\",\"r_to\":\"test_r\"},\"testDto_rs\":[{\"r_id\":\"\",\"r_to\":\"test_rs1\"},{\"r_id\":\"22\",\"r_to\":\"test_rs2\"}]}";
Gson gson = new Gson();
TestDto testDto = gson.fromJson(requestBody, TestDto.class);
ValidateUtil.valid(testDto);
} catch (Exception e) {
e.printStackTrace();
}
}
}