zoukankan      html  css  js  c++  java
  • 探索guava(一)——前置条件Preconditions类

    作用

    可以简洁的完成参数检验,在进行业务逻辑代码前进行前置判断。并且避免了冗长的if语句。guava将所有检验的API都放置于Preconditions类中

    API

    Preconditions类大致分为6种提供参数检验的方法,每种方法都有三个重载方法。重载方法的参数意义是:

    • 仅有待校验的参数:抛出的异常中没有错误消息;
    • 有一个Object对象作为额外参数:抛出的异常使用Object.toString() 作为错误消息;
    • *有一个String对象作为额外参数,还有一个Object[]参数,这两个参数也是适用于异常错误消息的,处理的方式类似于String.format将Object的参数按顺序替换掉String中的占位符(如%s)
    • 方法声明(不包括额外参数)描述检查失败时抛出的异常
      checkArgument(boolean) 检查boolean是否为true,用来检查传递给方法的参数。 IllegalArgumentException
      checkNotNull(T) 检查value是否为null,该方法直接返回value,因此可以内嵌使用checkNotNull。。 NullPointerException
      checkState(boolean) 用来检查对象的某些状态。 IllegalStateException
      checkElementIndex(int index, int size) 检查index作为索引值对某个列表、字符串或数组是否有效。index>=0 && index<size *。 IndexOutOfBoundsException
      checkPositionIndex(int index, int size) 检查index作为位置值对某个列表、字符串或数组是否有效。index>=0 && index<=size *。 IndexOutOfBoundsException
      checkPositionIndexes(int start, int end, int size) 检查[start, end]表示的位置范围对某个列表、字符串或数组是否有效* IndexOutOfBoundsException

    实例

    如:我们在做登录操作的方法中,在未用前置条件前,代码可能会如下:

     1 public User login(String userName,String password){
     2     if(StringUtils.isEmpty(userName) || StringUtils.isEmpty(password)){
     3         throw new RuntimeException("用户名或密码不能为空");
     4     }
     5     User user = userService.queryUserByUserNameAndPassword(userName,password);
     6     if(null == user){
     7         throw new RuntimeException("用户名或密码错误");
     8     }
     9     //…………………………………………省略业务逻辑…………………………………………
    10 }

    当使用了Preconditions类后

    public User login(String userName,String password){
           Preconditions.checkArgument(!(StringUtils.isEmpty(userName) || StringUtils.isEmpty(password)),"用户名或密码不能为空");
           User user = userService.queryUserByUserNameAndPassword(userName,password);
           Preconditions.checkNotNull(user,"用户名或密码错误");
           //…………………………………………省略业务逻辑…………………………………………
    }

    思考

    相信大家也发现了,Preconditions类与Assert断言类的思想基本是一致的,通过这个思想,我们也可以实现属于自己的断言类从而提升自己的开发效率。

    假设一个场景,我们是基于接口开发工作的,接口通过JSON传递数据给前端。此时我们先定义一个JSON的结构。

    public class ResponseEntity<T> implements Entity<T>,Serializable{
    
        private static final long serialVersionUID = 1L;
    
        //数据实体
        private T data;
        
        //结果码
        private Integer code;
        
        //错误描述
        private String message;
        
        //…………
    }

    自定义一个异常类

    public class GlobException extends RuntimeException{
    
        private static final long serialVersionUID = 1L;
    
        private String message;
        
        private Integer code;
    }

    定义自己的前置条件类(断言类)

    /**
     * 断言类
     * @author cjl
     */
    public abstract class Assert {
    
        /**
         * 断言对象不为空,若对象为空则报异常
         * @param obj 待校验对象
         * @param message 异常信息
         */
        public static void notNull(Object obj,String message){
            if(obj == null)
                throw new GlobException(message);
        }
        
        /**
         * 断言对象不为空,若对象为空则报异常
         * @param obj 待校验对象
         */
        public static void notNull(Object obj){
            Assert.notNull(obj, "The Object can't null");
        }
        
        /**
         * 断言数字不能为零,若数字为零则报异常
         * @param num 待校验数字
         * @param message 异常信息
         */
        public static void notZero(Integer num,String message){
            Assert.notNull(num);
            if(num.intValue() == 0)
                throw new GlobException(message);
        }
        
        /**
         * 断言数字不能为零,若数字为零则报异常
         * @param num 待校验数字
         */
        public static void notZero(Integer num){
            Assert.notZero(num,"The number can't equals zero");
        }
        
        /**
         * 断言字符串不能为空,若字符串为空则报异常
         * @param string 待校验字符串
         * @param message 异常信息
         */
        public static void notEmpty(String string,String message){
            if(StringUtils.isEmpty(string))
                throw new GlobException(message);
        }
        
        /**
         * 断言字符串不能为空,若字符串为空则报异常
         * @param string 待校验字符串
         */
        public static void notEmpty(String string){
            Assert.notEmpty(string,"The string can't empty");
        }
        
        /**
         * 断言该布尔值为true,若为false则抛异常
         * @param expression 待校验布尔值
         * @param message  异常信息
         */
        public static void isTrue(boolean expression,String message){
            if(!expression)
                throw new GlobException(message);
        }
        
        /**
         * 断言该布尔值为true,若为false则抛异常
         * @param expression 待校验布尔值
         */
        public static void isTrue(boolean expression){
            Assert.isTrue(expression,"The expression not true");
        }
    }

    这时候在定义一个全局异常处理类,这里使用的是Spring Mvc的@ControllerAdvice注解

    **
     * 全局异常处理
     * @author cjl
     */
    @ControllerAdvice
    public class ExceptionHandlers {
    
        @SuppressWarnings("rawtypes")
        @ResponseBody
        @ExceptionHandler(GlobException.class)
        public ResponseEntity<?> exceptionHandler(GlobException exception){
            outException(exception);
            return new ResponseEntity(exception);
        }
    
        /**
         * 异常输出
         * @param exception
         */
        private void outException(GlobException exception) {
            String content = String.format("****************系统发生异常(%s)************************", exception.getMessage());
            System.out.println(content);
        }
        
    }

    和上面的例子一样,我们现在实现一个完成登录的接口。

    @RequestMapping("/login")
        public ResponseEntity<?> login(String userName,String password){
            Assert.isTrue(!(StringUtils.isEmpty(userName)||StringUtils.isEmpty(password)),"用户名或密码不能为空");
            User user = userService.queryByUserNameAndPassword(userName, password);
            Assert.notNull(user,"用户名或密码错误");
            return ResponseEntity.success(user);
    }

    现在我们传用户名和密码,其中账号为空:

    接下来传错误的用户名和密码 

    正确的账号密码,完成登录

  • 相关阅读:
    配置文件配置网络
    安装Linux centos 7.3
    java二维字符数组的输入
    前端保存JSON文件到本地
    在Springboot中使用swagger2
    Vue better-scroll使用指南
    解决端口占用问题
    CheckSum(校验和)计算
    区分按字寻址与按字节寻址
    进制转换
  • 原文地址:https://www.cnblogs.com/kailejun/p/7282115.html
Copyright © 2011-2022 走看看