Java中都可以以对象做为传输的形式,所有的本地接口,dubbo接口调用,都是要和对象打交道的
作为很平常的一个接口之间的调用,对于接口中传递对象的参数校验是必不可少的,如果说对象内容较少,一个两个if就可以验证完毕,但是当接口参数超过10个,还要对内部参数进行:非空,是否大于xxx小于xxx,长度不能超过多少的时候,就很头疼了。第一是浪费时间,第二是修改的时候可读性也不好,很有可能改错,或者觉得不方便。
最近在项目中遇到了一个很不错的解决方法,自己试了下,也记录下,以后会用上。使用该方法的好处如图所示。
假设一个接口需要,学生(Student),和老师(Teacher)对象,这两个对象的内部参数,有部分不能为空,有部分不能取别的值,按照以往的做法就很麻烦,每个内部参数可能至少有一个或多个if验证(先验证是否为空,在验证是否是某些值)。
但是使用了这种拓展方法,就可以通过注解的方式,制定一个统一的参数验证方法,改的时候也非常简单。
实现过程如下:
1.首先,pom中添加
<dependency>
<groupId>net.sf.oval</groupId>
<artifactId>oval</artifactId>
<version>1.81</version>
</dependency>
oval 就是这次起核心作用的扩展包,他的任务就是,提供在对象或者参数上注解,然后通过内部提供的validate方法,对相关对象和接口统一验证。
2.待验证的对象,以下列代码为例,将所需注解,和如果验证不通过的返回message及errorCode包装好
package zxy.test.dto;
import net.sf.oval.constraint.Length;
import net.sf.oval.constraint.Max;
import net.sf.oval.constraint.Min;
import net.sf.oval.constraint.NotNull;
public class Student {
@NotNull(errorCode="9001",message="学生姓名不能为空")
private String name;
@Length(min=1,max=3,errorCode="9010",message="请检查年龄是否合规")
private int age;
@Max(value=1,errorCode="9011",message="请检查性别是否合规,0是男生,1是女生")
@Min(value=0,errorCode="9012",message="请检查性别是否合规,0是男生,1是女生")
private int sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", sex=" + sex + "]";
}
}
3.验证工具类 ,其中 BaseResp,和RespEnum是我建的验证返回对象,和枚举,按具体情况修改。
package zxy.test.util;
import java.util.List;
import net.sf.oval.ConstraintViolation;
import net.sf.oval.Validator;
import zxy.test.dto.BaseResp;
import zxy.test.dto.RespEnum;
public class validKit {
public static BaseResp valid(Object obj) {
Validator validator = new Validator();
List<ConstraintViolation> list = validator.validate(obj);
BaseResp resp = new BaseResp();
//只要list不为空,就可以判断是验证没有通过,一般只用获取其中一条错误返回即可
if (!list.isEmpty()) {
resp.setMessage(list.get(0).getMessage());
resp.setCode(list.get(0).getErrorCode());
//下面循环,只是为了展示验证结果,实际中按业务需求
for (ConstraintViolation constraintViolation : list) {
System.out.println("对象验证结果,返回码:"+constraintViolation.getErrorCode()+",返回信息"+constraintViolation.getMessage());
}
} else {
resp.setCode(RespEnum.SUCCESS.code);
resp.setMessage(RespEnum.SUCCESS.message);
}
return resp;
}
}
package zxy.test.dto;
public class BaseResp {
private String code;
private String message;
@Override
public String toString() {
return "BaseResp [code=" + code + ", message=" + message + "]";
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
package zxy.test.dto;
public enum RespEnum {
SUCCESS("SUCCESS", "0000");
public String code;
public String message;
RespEnum(String code, String message) {
this.code = code;
this.message = message;
}
}
4.工具类的调用
只要成功就会返回code :0000,其余的失败都会自动在验证工具类中,把事先用注解配置好的code,和message返回到返回对象中,这样,只要判断返回对象code是否为0000就可以了
public class app {
public static void main(String[] args) {
//构造参数
Student student=new Student();
student.setAge(9999);
student.setSex(888);
Teacher teacher=new Teacher();
//验证学生
BaseResp respStudent= validKit.valid(student);
//验证老师
BaseResp respTeacher=validKit.valid(teacher);
//返回值判断
if(!RespEnum.SUCCESS.code.equals(respStudent.getCode())
||!RespEnum.SUCCESS.code.equals(respTeacher.getCode()) ){
System.err.println(respStudent.toString());
System.err.println(respTeacher.toString());
return;
}
//假设访问方法
StudyActivity activity=new StudyActivity();
activity.mathClass(student,teacher);
}
}
附demo链接:
该demo包括了excel 通用解析,和java参数统一验证的完整方法,可直接执行