精华内容
下载资源
问答
  • java后台非空验证

    千次阅读 2018-07-27 17:07:17
    if ((!"".equals(isDisplay)) && isDisplay != null) { ////// }  
    if ((!"".equals(isDisplay)) && isDisplay != null) {
    
    //
    }

     

    展开全文
  •  博主在平时写代码的时候,喜欢先对方法参数进行一遍非空验证,然后才开始处理业务逻辑。当然,这有两方面原因,第一是参加工作那会,带我的老司机写代码时教我们的,第二是我觉得这样能够保证程序更加严密,更加...

        博主在平时写代码的时候,喜欢先对方法参数进行一遍非空验证,然后才开始处理业务逻辑。当然,这有两方面原因,第一是参加工作那会,带我的老司机写代码时教我们的,第二是我觉得这样能够保证程序更加严密,更加可靠,消耗更少的资源(比如添加了非空校验,可以阻止调用数据库)。

        由于代码写的多,所以校验也就写的多,有时候一个方法写的校验比业务逻辑还多,会比较麻烦。看看下面这段代码,就是平时写的校验:

    @Transactional
    public void downloadFromBaseReagent(List<BaseReagentView> baseReagentViews, String orgId,
    									String userId) {
    	logger.info("【从平台产品库中下载产品信息到机构产品库】orgId = {} , userId = {} , baseReagentViews = {}", orgId,
    		userId, baseReagentViews);
    
    	if (ProString.isBlank(orgId)) {
    		logger.warn("【参数orgId为空】");
    		throw new IllegalArgumentException("从平台产品库中下载产品信息到机构产品库,参数orgId为空");
    	}
    	if (ProString.isBlank(userId)) {
    		logger.warn("【参数userId为空】");
    		throw new IllegalArgumentException("从平台产品库中下载产品信息到机构产品库,参数userId为空");
    	}
    	if (ProCollection.isEmpty(baseReagentViews)) {
    		logger.warn("【参数baseReagentViews为空】");
    		throw new IllegalArgumentException("从平台产品库中下载产品信息到机构产品库,参数baseReagentViews为空");
    	}
    	List<CoreReagentView> coreReagents = generateOrgReagent(baseReagentViews, orgId, userId);
    
    	coreReagentMapper.batchInsert(coreReagents);
    
    }

        上面这段代码,非空校验就写了很大一部分,所以从一年前博主就在思考通过一些工具类帮助程序员做这种非空校验,比如Spring MVC的@RequestParam,参考@RequestParam的思路,博主花了三个小时写了一个简单版(Beta-1.0.0),测试了一下,可行,先来写篇博客,然后再慢慢完善。

        工具的实现是自定义注解+AOP,主要有两个类,下面给出源代码

        自定义注解:ParamRequired.java

    /**
     * Copyright (c) 2015 - 2016 Eya Inc.
     * All rights reserved.
     */
    package com.cdelabcare.common.annotation;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * 
     * @create ll
     * @createDate 2016年12月2日 上午11:20:34
     * @update 
     * @updateDate 
     */
    // 作用域,这里限制只能作用在参数上
    @Target(ElementType.METHOD)
    // 注解的生命周期,这里限制在运行时有效
    @Retention(RetentionPolicy.RUNTIME)
    //用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。Documented是一个标记注解,没有成员。
    @Documented
    public @interface ParamRequired {
        /**
         * 需要校验的参数索引,下表从0开始
         * @Author : ll. create at 2016年12月2日 下午3:07:16
         */
        int[] indexs();
    
        /**
         * 字符串不能为空字符串,即不能为"",默认true
         * @Author : ll. create at 2016年12月2日 下午3:07:42
         */
        boolean stringNotEmpty() default true;
    
        /**
         * {@code Collection}不能为空集合,默认为true
         * @Author : ll. create at 2016年12月2日 下午3:08:03
         */
        boolean collectionNotEmpty() default true;
    
        /**
         * {@code Map}不能为空,默认为true
         * @Author : ll. create at 2016年12月2日 下午3:08:54
         */
        boolean mapNotEmpty() default true;
    
    }
    

    AOP切面类:ParamRequiredAspect

    
    
    
    import com.eya.common.annotation.ParamRequired;
    
    import org.apache.commons.collections.CollectionUtils;
    import org.apache.commons.collections.MapUtils;
    import org.apache.commons.lang3.ArrayUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.apache.ibatis.javassist.ClassClassPath;
    import org.apache.ibatis.javassist.ClassPool;
    import org.apache.ibatis.javassist.CtClass;
    import org.apache.ibatis.javassist.CtMethod;
    import org.apache.ibatis.javassist.bytecode.CodeAttribute;
    import org.apache.ibatis.javassist.bytecode.LocalVariableAttribute;
    import org.apache.ibatis.javassist.bytecode.MethodInfo;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.springframework.core.DefaultParameterNameDiscoverer;
    import org.springframework.core.ParameterNameDiscoverer;
    import org.springframework.stereotype.Component;
    
    import java.lang.reflect.Method;
    import java.lang.reflect.Modifier;
    import java.util.Collection;
    import java.util.Map;
    
    /**
     * 参数非空校验的切面类
     * <p>扫描带有{@code ParamRequired}注解的方法
     *
     * @create ll
     * @createDate 2016年12月2日 上午11:57:38
     * @update
     * @updateDate
     */
    @Aspect
    @Component
    public class ParamRequiredAspect {
    
    	// shared param discoverer since it caches data internally
    	private static final ParameterNameDiscoverer paramNameDiscoverer = new DefaultParameterNameDiscoverer();
    
    	/**
    	 * 拦截带@ParamRequired注解的方法,校验参数是否为空
    	 *
    	 * @Author : ll. create at 2016年12月2日 下午3:01:44
    	 */
    	@Before("@annotation(com.wyying.consult.common.annotation.ParamRequired)")
    	public void beforeDo(JoinPoint joinPoint) throws Exception {
    
    		//拦截的实体类
    		Object target = joinPoint.getTarget();
    
    		//拦截的方法名称
    		String methodName = joinPoint.getSignature().getName();
    		//拦截的放参数类型
    		Class<?>[] parameterTypes = ((MethodSignature) joinPoint.getSignature()).getMethod().getParameterTypes();
    		//拦截的方法
    		Method method = target.getClass().getMethod(methodName, parameterTypes);
    
    		// 获取参数名称
    		//String[] paramNames = getFieldsName(this.getClass(), target.getClass().getName(), methodName);
    		String[] paramNames = getParameterNames(method);
    
    		//拦截的方法参数(值)
    		Object[] args = joinPoint.getArgs();
    
    		// 获取方法的注解
    		ParamRequired paramRequired = method.getAnnotation(ParamRequired.class);
    		// 获取方法注解的indexs属性的值
    		int[] indexs = paramRequired.indexs();
    		// 处理没有指定参数索引的情况:如果没有指定参数索引,则表示校验所有参数
    		if (ArrayUtils.isEmpty(indexs)) {
    			indexs = new int[args.length];
    			for (int i = 0, len = args.length; i < len; i++) {
    				indexs[i] = i;
    			}
    		}
    		// 注解的三个参数,分别为:String是否不能为空字符串,集合是否不能为空集合,Map是否不能为空
    		boolean stringNotEmpty = paramRequired.stringNotEmpty();
    		boolean collectionNotEmpty = paramRequired.collectionNotEmpty();
    		boolean mapNotEmpty = paramRequired.mapNotEmpty();
    
    		// 依次校验是否有空值
    		Object tmpValue = null;
    		int illegalIndex = -1;
    		for (int i : indexs) {
    			tmpValue = args[i];
    			if (tmpValue == null) {
    				illegalIndex = i;
    			}
    			if (tmpValue instanceof String) {
    				if (stringNotEmpty && StringUtils.isBlank((String) tmpValue)) {
    					illegalIndex = i;
    				}
    			} else if (tmpValue instanceof Collection<?>) {
    				if (collectionNotEmpty && CollectionUtils.isEmpty((Collection<?>) tmpValue)) {
    					illegalIndex = i;
    				}
    			} else if (tmpValue instanceof Map<?, ?>) {
    				if (mapNotEmpty && MapUtils.isEmpty((Map<?, ?>) tmpValue)) {
    					illegalIndex = i;
    				}
    			} else if (tmpValue instanceof Object[]) {
    				if (collectionNotEmpty && ArrayUtils.isEmpty((Object[]) tmpValue)) {
    					illegalIndex = i;
    				}
    			}
    			// 校验不通过,直接处理结果
    			if (illegalIndex != -1) {
    				resultHandler(target, methodName, paramNames, illegalIndex);
    			}
    		}
    	}
    
    	/**
    	 * 处理校验结果
    	 *
    	 * @param obj        被拦截的对象
    	 * @param methodName 方法名称
    	 * @param paramNames 参数数组
    	 * @param index      参数索引
    	 * @Author : ll. create at 2016年12月2日 下午2:52:23
    	 */
    	private void resultHandler(Object obj, String methodName, String[] paramNames, int index) {
    		String msgTemplate = "调用%s.%s时,参数%s为空";
    		String msg = String.format(msgTemplate, obj.getClass().getName(), methodName, paramNames[index]);
    		throw new IllegalArgumentException(msg);
    	}
    
    
    	/**
    	 * 获取方法的参数列表
    	 * <p>用于替代getFieldsName方法</p>
    	 *
    	 * @param method {@link Method}
    	 * @return 指定方法的参数列表
    	 */
    	public static String[] getParameterNames(Method method) {
    		return paramNameDiscoverer.getParameterNames(method);
    	}
    
    }
    

         通过上面2个类,就可以实现验证方法参数非空了,使用的时候,在要校验的方法上,加上注解@ParamRequired即可,那么将最上面的业务代码就可以改成如下这样:

    @Transactional
    @ParamRequired(indexs = { 0, 1, 2 })
    public void downloadFromBaseReagent(List<BaseReagentView> baseReagentViews, String orgId,
    									String userId) {
    	logger.info("【从平台产品库中下载产品信息到机构产品库】orgId = {} , userId = {} , baseReagentViews = {}", orgId,
    		userId, baseReagentViews);
    
    	List<CoreReagentView> coreReagents = generateOrgReagent(baseReagentViews, orgId, userId);
    
    	coreReagentMapper.batchInsert(coreReagents);
    }

        如果在调用上述方法时,参数为空,则会抛出异常,输出的异常信息描述如下

    调用com.eya.service.test.downloadFromBaseReagent时,参数baseReagentViews为空

        修改之后,方法体变得简单多了,只需要专注于解决业务问题即可,太棒了。

        注解除了indexs,还有其他三个参数,通过看源代码就能理解,这里不再累述。

        希望该工具能够帮助和我一样对程序严谨性和健壮性有要求的朋友。如果朋友们有更好建议,欢迎指导和交流。

        在最后,谈一下使用AOP带来的一个缺陷,如果从方法内部调用调用当前类的另一个方法,比如beanA中的方法method1和method2,都添加了@ParamRequired注解,然后method1中调用了method2,AOP不会对这样的调用进行拦截,这是和代理相关的问题,这里不详细介绍。解决这种问题有两种思路:

        1、(Spring官方推荐,但不可取)在外部将调用method1和method2分开,即先调用method1,再调用method2来解决这种问题。但是这样会使我们的逻辑变得紊乱。

        2、使用AopContext获取当前代理对象,然后调用method2,可以触发AOP拦截(详细介绍请上车:http://www.tuicool.com/articles/NFJNRf

    转载于:https://my.oschina.net/simpleton/blog/798871

    展开全文
  • Java自定义注解验证非空参数

    千次阅读 2020-07-06 15:51:59
    很讨厌spring自带的验证框架,所以使用喜欢自定义注解的方式进行验证,需要改验证规则也可以直接改,废话不多说,上代码 aop层 package com.abb.min.business.util.bean; import ...

    自定义注解的方式进行验证,分享一下,支持参数对象字段验证、参数字段验证,需要改验证规则也可以直接改,废话不多说,上代码

    aop层

    package com.abb.min.business.util.bean;
    
    
    import com.abb.min.business.Exception.UsException;
    import com.alibaba.druid.util.StringUtils;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint;
    import org.springframework.core.DefaultParameterNameDiscoverer;
    import org.springframework.core.ParameterNameDiscoverer;
    import org.springframework.stereotype.Component;
    import org.springframework.web.multipart.MultipartFile;
    
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.HashMap;
    
    @Aspect
    @Component
    
    /**
     * 功能描述: 参数校验
     * @param null:
     * @return:
     * @auther: nike
     * @date: 2020/07/05 17:19
     * @description:
     */
    public class RequestRequireAspect {
    
    
    
        public RequestRequireAspect() {
        }
    
        @Pointcut("@annotation(com.abb.min.business.util.bean.RequestRequire)")
        public void parameterInteceptor() {
        }
    
        @Around("parameterInteceptor()")
        public Object around(ProceedingJoinPoint pjp) throws Throwable {
            Object[] argss = pjp.getArgs();
            MethodInvocationProceedingJoinPoint mjp = (MethodInvocationProceedingJoinPoint) pjp;
            MethodSignature signature = (MethodSignature) mjp.getSignature();
            Method methodd = signature.getMethod();
            RequestRequire  require = methodd.getAnnotation(RequestRequire.class);
            if(require.parameter()==Object.class){
                String classType = pjp.getTarget().getClass().getName();
                String methodName = pjp.getSignature().getName();
                // 参数值
                Object[] args = pjp.getArgs();
                Class<?>[] classes = new Class[args.length];
                for (int k = 0; k < args.length; k++) {
                    if (args[k] instanceof MultipartFile || args[k] instanceof ServletRequest || args[k] instanceof ServletResponse) {
                        return null;
                    }
                    if (!args[k].getClass().isPrimitive()) {
                        Class s = args[k].getClass();
                        classes[k] = s == null ? args[k].getClass() : s;
                    }
                }
                ParameterNameDiscoverer pnd = new DefaultParameterNameDiscoverer();
                Method method = Class.forName(classType).getMethod(methodName, classes);
                String[] parameterNames = pnd.getParameterNames(method);
                for (int i = 0; i < parameterNames.length; i++) {
                    if(args[i]==null||StringUtils.isEmpty(args[i].toString())){
                        throw new UsException("参数"+parameterNames[i]+"不允许为空");
                    }
                }
                return pjp.proceed();
            }
            String fieldNames=require.require().replace(",", ",");
            Object parameter=null;
            for(Object pa:argss){
                //class相等表示是同一个对象
                if (pa.getClass()==require.parameter() ) {
                    parameter=pa;
                }
            }
            Class cl=parameter.getClass();
            for(String fieldName:fieldNames.split(",")){
                Field f=cl.getDeclaredField(fieldName);
                f.setAccessible(true);
                Object value=f.get(parameter);
                if(value==null||StringUtils.isEmpty(value.toString())){
                  throw new UsException("参数"+fieldName+"不允许为空");
                }
            }
            //放行
            return pjp.proceed();
        }
    }
    

    定义自定义注解

    package com.abb.min.business.util.bean;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * @author nike
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface RequestRequire {
    
        /**
         * 接口所需要验证参数,小写逗号隔开
         */
        String require() default "";
    
        /**
         *传递参数的对象类型
         */
        Class<?> parameter() default Object.class;
    }
    

    大功告成~直接注解到方法上即可
    在这里插入图片描述

    展开全文
  • 非空验证

    2020-05-11 12:52:29
    string类型做非空验证 if("".equals(参数) || null == 参数){ System.out.print("为空"); } 注:顺序反了会报空指针 date类型非空验证 直接判断 == null; 三种空的区别 类型 描述 isEmpty() 分配了内存空间...

    string类型做非空验证

    if("".equals(参数) || null == 参数){
    System.out.print("为空");
    }
    
    注:顺序反了会报空指针

    date类型非空验证

    直接判断 == null;

    三种空的区别

    类型描述
    isEmpty()分配了内存空间,值为空,是绝对的空,是一种有值(值 = 空)
    “”分配了内存空间,值为空字符串,是相对的空,是一种有值(值 = 空字串)
    null是未分配内存空间,无值,是一种无值(值不存在)
    展开全文
  • 使用了自定义注解,根据反射拿到注解和值判断该成员属性是否必须不为空 首先是自定义注解 import java.lang.annotation.ElementType; import java.lang.annotation.Retention;...import java.lang.annotatio
  • Java非空处理

    千次阅读 2019-01-20 17:00:31
    导语 我之前太年轻,经常在项目中做很多if/...有时候在进行接口对接的时候,要是忘记非空判断就会抛出空指针异常。下面结合几位大佬的结晶,总结梳理一下: 业务中的空值 场景 存在一个UserSearchService用...
  • 1定义一个在方法上作用的注解@Retention(RetentionPolicy.RUNTIME) // 表示注解在运行时依然存在@Target(ElementType.METHOD)@...}2定义一个拦截类,拦截被注解的方法,并验证注解中指定的方法是否为空public...
  • JAVA参数统一验证扩展

    千次阅读 2018-09-27 18:04:29
     作为很平常的一个接口之间的调用,对于接口中传递对象的参数校验是必不可少的,如果说对象内容较少,一个两个if就可以验证完毕,但是当接口参数超过10个,还要对内部参数进行:非空,是否大于xxx小于xxx,长度不能...
  • java非空验证使用的是springboot的validation进行验证 一、需要引入spring-boot-starter-validation包 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core&...
  • 请求参数非空校验 写项目的时候请求参数有时候有好几十个字段都要做非空校验,挨个写if难免有点显low,写个通用工具类,任何接口的请求参数需要做非空校验的时候都能用。 思路 方法需要传入一个requestMap和一个...
  • // 验证非空 String msg = new String(); msg = msg.length()==0?StringUtils.isBlank((mallMerchants.getShopname()))?"店铺名称不能为空!":"":msg; msg = msg.length()==0?StringUtils.isBlank((mallMerchants....
  • 为了避免对大量参数进行过多的非空校验,我们可以自定义一个非空验证的注解,因为spring自带的@RequestParam并不能对参数进行非空 准备工作 首先需要创建一个spring boot项目,并引入相关maven依赖,pom文件如下: ...
  • 使用注解统一校验参数非空

    千次阅读 2019-08-21 12:40:38
    System.out.println("==========非空校验失败========="); throw new IllegalArgumentException("[" + annotation.content() + "]为空"); } System.out.println(fieldName + "长度:" + String.valueOf...
  • Hibernate validator限制参数非空方法

    千次阅读 2016-03-24 17:16:56
    Hibernate validator有下面三种注释来限制输入参数必须非空 @NotBlank Validate that the annotated string is not null or empty. The difference to NotEmpty is that trailing whitespaces are getting ...
  • 我们在写接口时,会对接口参数进行一些验证,比如非空必填、字段长度等等,代码就会有大量的if - else,重复的代码毫无意义。为了提升方便性和代码的简洁性,JAVA提供了@validated和@valid注解验证,但这只能在...
  • 自定义注解,来对对应的方法进行入参校验,为空返回参数错误 新建注解类@interface ParamsVerify @Target(ElementType.METHOD)//枚举,表示注解可能出现在的地方 @Retention(RetentionPolicy.RUNTIME)//运行时保留...
  • 使用Mybatis多条件非空验证查询错误

    千次阅读 2017-12-11 15:29:03
    之前没写嵌套if语句,上面两个参数存在即可正常运行,如不存在报如下异常 :     org.apache.ibatis.ognl.OgnlException: source is null for getProperty(null, "brandName")   之后加上嵌套if ...
  • 对于我们工程师来说,代码中都是非空验证,is null 这一看就是新手写的代码,如何优雅...1.1对象参数非空验证: ①(利用spring valid来解决) @NotNull(message = "数据录入方式不能为空,请检查后重新填写") private I
  • return result.errorResult(MsgConstant.REQUEST_PARAMETER_ERROR.getCode(), backStr("请求参数 %s 不能全为空", Arrays.asList(notAllNull))); } else { logger.debug("参数校验成功"); return joinPoint....
  • import java.util.Objects; /* * Objects类中的静态方法 * public static <T> T requireNonNull(T obj):查看指定引用对象不是null * 源码: * public static <T> T requireNonNull(T obj){ * ...
  • 欢迎关注博主公众号:【纯洁的明依】文章由陈晓阳原创。 本人微信:chenxiaoyangzxy. 免费提供本人大量学习资料。...因为我们要做一个非空校验参数,那么使用注解就必须把 非空的字段传入进去。 这些非空的...
  • JDK7里面新增的Objects类,本类由一些操作对象的静态工具方法构成,这些工具方法包括了非空检查、方法的非空参数检查、 比较对象的hashCode、为对象返回一个字符串表示、比较两个对象等。 本文是以java8版本介绍...
  • 工作中遇到针对API中存在的实体类的非空校验,如果不封装只能一个一个获取再校验。比较麻烦,所以写了个通用工具类,通过反射去实现效果 /** * 功能描述:对象非空校验 * * @author: hfanss * @date: 2021-...
  • 参数验证是一个常见的问题,无论是前端还是后台,都需要对用户输入进行验证,以此来保证系统数据的正确性。对于web来说,有些人可能理所当然的想在前端验证就行了,但是这样是非常错误的想法,前端代码对于用户来说...
  • * 〈注解验证参数〉 * * @param obj * @throws DataCheckException * @see [相关类/方法](可选) * @since [产品/模块版本](可选) */ public static <T> void validate(T obj) throws ...
  • mybatis多个参数 判断非空

    千次阅读 2017-05-03 09:38:21
    只传一个参数判断非空的情况&lt;if test="type!=null and type!=''"&gt; AND type = #{type} &lt;/if&gt; b.传多个参数不判断非空的情况AO层的函数方法 Public User selectUser...
  • Spring Api请求参数嵌套类验证 Java Api设计中参数的校验是Api接口功能的重要组成部分;如何对嵌套实体类对校验呢? 比如:银行卡绑定功能Api,请求接口bingCard,请求实体UserRequest,UserReuest又嵌套了一个银行卡...
  • 用注解和aop结合实现对方法参数非空校验 猜想 探索,没有实际应用 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import...
  • java 链式表单验证

    2020-12-30 19:35:13
    这种验证方法重复性代码较多, 比如参数不能为空判断,如果我有20个字段需要非空判断,我就要写20个条件判断 这种代码重复性高且没有质量 下面给大家推荐链式条件查询 Chaining demoChaining = new ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 15,370
精华内容 6,148
关键字:

java参数非空验证

java 订阅