|
自定义参数校验注解
------------------------------------------------
目的:
使用springmvc自带的校验参数的注解@Valid,不支持webservice接口。建议自定义注解,利用AOP切面进行参数校验。
------------------------------------------------
自定义注解
- /**
- * <pre>
- * 描述:字段校验的注解
- * 举例:
- * 校验长度@FV(names="REGEX", pattern="^[\\s\\S]{0,1000}$", msg="长度必须小于等于1000")
- * @FV(names="TRIM,REGEX", pattern="^(0|1|2)$", msg="值超出范围:{0:所有;1:教职工;2:学生}")
- * </pre>
- * @author 01116253
- * @since 1.0
- */
- @Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
- @Target({ElementType.FIELD})//定义注解的作用目标**作用范围字段、枚举的常量/方法
- @Documented//说明该注解将被包含在javadoc中
- public @interface FV {
-
- /**
- * 字段校验方法 ,如NOTNULL,NOTBLANK,REGEX,TRIM,CODEVALID,NAMEVALID。英文逗号分隔。
- * @return
- */
- String names() default "";
- /**
- * 字段正则校验时的表达式
- * @return
- */
- String pattern() default "";
- /**
- * 字段校验失败的描述
- * @return
- */
- String msg() default "";
- }
复制代码
- /**
- * <pre>
- * 描述:获取到注解
- * </pre>
- * @author 01116253
- * @since 1.0
- */
- public class FieldValid {
-
- private FV meta;
- private Field field;
- private Object val;
-
- public FieldValid(){}
-
- public FieldValid(FV meta, Field field, Object val) {
- super();
- this.meta = meta;
- this.field = field;
- this.val=val;
- }
- }
复制代码- /**
- * 描述:注解校验类的工厂
- *
- * @author Administrator
- * @since 1.0
- */
- public class ValidFactory {
- public static final String NOTNULL="NOTNULL";
- public static final String NOTBLANK="NOTBLANK";
- public static final String REGEX="REGEX";
- public static final String TRIM="TRIM";
- public static final String CODEVALID="CODEVALID";
- public static final String NAMEVALID="NAMEVALID";
-
- public IValid createValid(String metaName){
- if(NOTNULL.equals(metaName)){
- return NotNullValid.getInstance();
- }
- if(NOTBLANK.equals(metaName)){
- return NotBlankValid.getInstance();
- }
- if(REGEX.equals(metaName)){
- return RegexValid.getInstance();
- }
- if(TRIM.equals(metaName)){
- return TrimValid.getInstance();
- }
- if(CODEVALID.equals(metaName)){
- return CodeValid.getInstance();
- }
- if(NAMEVALID.equals(metaName)){
- return NameValid.getInstance();
- }
- throw new MyException("未设置"+metaName+"校验处理器");
- }
- }
复制代码- public interface IValid {
- static final LoggerDecorate logger = LoggerDecorateFactory.getLogger(IValid.class);
- String valid(FieldValid f, Object bean);
- }
复制代码- /**
- * 描述:非空校验举例
- *
- * @author Administrator
- * @since 1.0
- */
- public class NotBlankValid implements IValid {
- private NotBlankValid() {
- }
- private static class SingletonFactory {
- private static NotBlankValid instance = new NotBlankValid();
- }
- /* 静态工程方法,创建实例 */
- public static NotBlankValid getInstance() {
- return SingletonFactory.instance;
- }
- public String valid(FieldValid f, Object bean) {
- StringBuilder err = new StringBuilder();
- FV meta = f.getMeta();
- Field field = f.getField();
- Object val = f.getVal();
- if (null==val || StringUtils.isBlank(val.toString())) {
- String message = meta.msg();
- if (StringUtils.isNotBlank(message)) {
- FieldUtil.createErrMsg(field, message, err);
- } else {
- err.append(field.getName());
- err.append("不能为空");
- }
- err.append(";");
- }
- return err.toString();
- }
- }
复制代码- /**
- * <pre>
- * 描述:运行时获取注解
- * </pre>
- * @author 01116253
- * @since 1.0
- */
- public class BaseBeanValid {
-
- /**
- * <pre>
- * 校验参数
- * </pre>
- * @throws IllegalArgumentException
- * @throws IllegalAccessException
- */
- public static <T> void validField(T bean) throws IllegalArgumentException, IllegalAccessException{
- List<FieldValid> fields = listFieldValid(bean);
- StringBuilder err = new StringBuilder();
- ValidFactory vf = new ValidFactory();
- IValid v = null;
- for(FieldValid f : fields){
- String names = f.getMeta().names();
- if(StringUtils.isBlank(names)){
- continue;
- }
- //多个,则按顺序校验,遇到第一个失败则返回
- String[] nameArray = names.split(",");
- for(String name : nameArray){
- v = vf.createValid(name); // 校验类实例
- String errmsg = v.valid(f, bean); // 校验结果
- if(StringUtils.isNotBlank(errmsg)){
- err.append(errmsg);
- break;
- }
- }
- }
- if(err.length()>0){
- throw new MyException(ResultCode.PARAM_ERROR, err.toString()); //参数校验异常
- }
- }
-
- /**
- * <pre>
- * 获取FieldMeta注解的字段
- * </pre>
- * @return
- * @throws IllegalAccessException
- * @throws IllegalArgumentException
- */
- private static <T> List<FieldValid> listFieldValid(T bean) throws IllegalArgumentException, IllegalAccessException{
- List<FieldValid> list = new ArrayList<FieldValid>();
- Class entity = bean.getClass();
- if(entity!=null){
- /*
- * 返回类中所有字段,包括公共、保护、默认(包)访问和私有字段,获取包括父类在内的所有字段
- * */
- List<Field> fields = BeanUtil.listField(entity);
- for(Field f : fields){
- //获取字段中包含fieldMeta的注解
- FV meta = f.getAnnotation(FV.class);
- if(meta!=null){
- f.setAccessible(true); //设置些属性是可以访问的
- Object val = f.get(bean);//得到此属性的值
- FieldValid sf = new FieldValid(meta, f, val);
- list.add(sf);
- }
- }
- }
- return list;
-
- }
- }
复制代码
------------------------------------------------
利用AOP切面进行参数校验
- /**
- * <pre>
- * 描述:切面记录请求日志,拦截各种接口
- * </pre>
- * @author 01116253
- * @since 1.0
- */
- @Aspect
- @Component
- public class LogAspect {
- private static LoggerDecorate logger = LoggerDecorateFactory.getLogger(LogAspect.class);
- private static final String REQ = "REQ";
- private static final String RSP = "RSP";
- @Pointcut("execution(* com.wisedu.api.message.controller..*Controller.*(..))"
- + "|| execution(* com.wisedu.api.app.controller..*Controller.*(..))"
- + "|| execution(* com.wisedu.api.transfer.controller..*Controller.*(..))")
- public void api() {
- }
- @Around("api()")
- public Object invoke(ProceedingJoinPoint pjp) throws Throwable {
- Object[] arguments = pjp.getArgs();
- validBaseReq(arguments);
-
- Object rsp = pjp.proceed();
-
- return rsp;
- }
- public void validBaseReq(Object... params) throws IllegalArgumentException, IllegalAccessException {
- if (ArrayUtils.isEmpty(params)) {
- return;
- }
- for (Object object : params) {
- if (null == object) {
- throw new MyException(ResultCode.PARAM_ERROR, "Bean参数不能为null");
- }
- if (object.getClass().isArray()) {
- Object[] objectArr = (Object[]) object;
- if (ArrayUtils.isNotEmpty(objectArr)) {
- for (Object item : objectArr) {
- validBaseReq(new Object[] { item });
- }
- }
- } else if ((object instanceof IBaseReq)) {
- ((IBaseReq) object).verify();
- BaseBeanValid.validField(object);
- }
- }
- }
-
- }
复制代码
------------------------------------------------
使用注解
- public class CheckSchoolAppCustomCReq implements IBaseReq{
-
- @FV(names="NOTBLANK,TRIM")
- private String schoolCode;
-
- @FV(names="NOTBLANK,TRIM")
- private String domainCode;
-
- @FV(names="NOTBLANK,TRIM")
- private String serverId;
- @FV(names="NOTBLANK,TRIM")
- private String appName;
- @FV(names="NOTBLANK,TRIM")
- private String appVersion;
- @Override
- public void verify() {
-
- }
-
- }
复制代码
|
|