实用开发篇1

实用开发篇1

1、ConfigurationProperties

1.1、工程的搭建

image-20220523233254613

image-20220523233343850

勾选lombok,其他的看情况自己手动添加,因为不是web服务所以不需要勾选web

image-20220523233411078

Finnish

image-20220523233423739

1.2、项目初始化配置

将原先的porperties文件修改为yml文件格式

image-20220523233517088

1.3、@ConfigurationPorperties

1概述

  • @ConfigurationPorperties这个注解,是可以对我们的实体类的属性进行属性注入的
  • 首先我们得有配置---yml
  • 其次我们得有所谓的实体类(Bean包,取什么名字都可以),并且这个对象是被SpringIOC容器所管控的
    • 因为这个实体类需要加载yml当中的属性,所以这个需要加载配置的实体类,他是需要被SpringIOC容器所管控的

2、配置文件的编写

# 我们这里单独配置一个供我们这个项目所使用的端口号
services:
  ipAddress: 172.16.1.1 # ip地址
  port: 8080 # ip地址的端口号
  timeout: -1 # 该地址的超时时间用不超时

3、实体类的创建

因为我们是配置类嘛,那就创建目录为config/ServletConfig的java文件

/**
 * 这是一个配置类,这个配置类会加载yml文件当中我们所需要的配置
 */
@Component // 你要加载SpringBoot的yml文件,那么你自己得是一个被SpringBoot所管控的容器
@ConfigurationProperties(prefix = "services")
@Data
public class ServletConfig {
    /**
     * 通过 @ConfigurationProperties,配置了前缀我可以读取到当中的配置
     * @Param ipAddress IP地址
     * @Param port IP地址的端口号
     * @Param  timeout IP地址的超时时间
     */
    private String ipAddress;
    private int port;
    private int timeout;
}

4、测试

获取这个Bean,然后我们打印一下地址吧

@SpringBootApplication
public class Demo8SpringbootConfigurationApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(Demo8SpringbootConfigurationApplication.class, args);
        ServletConfig servletConfig = run.getBean(ServletConfig.class);
        System.out.println(servletConfig);
    }

}

image-20220523235604159

  • 如果使用了@ConfigurationProperties这个注解
  • 类上加上这个注解的话,并且配置好前缀--prefix
    • image-20220523235707957
    • 如果有多级目录的话就 . 就行了
  • 该配置类当中的属性名一定要和yml当中的父级目录下(services)的属性名一致,不然无法进行加载

例如我现在将timeout改为timeouts

image-20220524000135761

我再来测试一下

image-20220524000154684

因为是long型的,所以默认值为0

1.4、问题的引出

如果是第三方的配置呢?我应该怎么引入?

  • 假设我yml文件当中配置了一条数据源(datasource)相关的配置,并且这个配置需要第三方Bean去加载呢?我应该怎么配置?
  • 这就是我们在高级当中需要解决的问题

导入druid数据源的依赖

<!-- 添加一个数据源druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <!-- 这个是第三方的,所以需要版本号 -->
    <version>1.1.16</version>
</dependency>

创建配置类dataSource

我们会通过这个配置类,获取到数据源对象 druidDataSource

/**
 * 数据源dataSource的配置类
 */
@Configuration // 这是一个配置类
public class dataSource {

    // 我这个配置类是获取数据源对象DataSource的
    @Bean
    public DruidDataSource getDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        return dataSource;
    }
}

测试方法

  • 加载我们的配置类
  • 通过配置类调用内部,加载数据源对象的方法--getDataSource()
  • 打印我们这个数据源对象的toString方法
  • image-20220524002408843
public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(Demo8SpringbootConfigurationApplication.class, args);
        ServletConfig servletConfig = run.getBean(ServletConfig.class);
        // System.out.println(servletConfig);

        // 获取自定义的druid的配置类
        dataSource dataSourceConfig = run.getBean(dataSource.class);
        // 通过这个配置类的方法获取到我们的数据源对象,并打印
        System.out.println(dataSourceConfig.getDataSource());
    }

打印出了这么一串结果

image-20220524002427232

  • 现在他给我显示的是这么一个格式,是数据源连接池 初始化 好以后的配置值
    • 现在这一套配置值并没有被初始化,因为druid只有他真正连接数据库的时候才会去处理,才会启动初始化
    • 现在这个样子就是懒加载的样子,内部的属性给你定义好了,因为你没有使用,所以所有值都是0
  • 这个不重要,我们现在讲究的是@ConfigurationProperties给第三方的组件定义值

配置值1,通过get和set

配置类方法的改造

这个数据源他不是一个对象吗,内部肯定有get和set方法嘛,我们这样给他赋值撒

image-20220524002916911

你看它这里有这么多属性,我们随便找几个吧

image-20220524003310496

/**
 * 数据源dataSource的配置类
 */
@Configuration // 这是一个配置类
public class dataSource {

    // 我这个配置类是获取数据源对象DataSource的
    @Bean
    public DruidDataSource getDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        // 通过set手动对某些属性进行赋值,可以随便设置,因为现在我们不需要连接数据库
        // 我们的目的是第三方Bean的属性绑定
        dataSource.setDriverClassName("com.mysql.cj.jdbc.driver"); // 设置驱动类名,那就设置个M8的吧
        dataSource.setEnable(true); // 布尔类型的,那我设置个true吧
        return dataSource;
    }
}

重新测试

image-20220524003601294

image-20220524003612948

配置值2--注解方式

yml文件配置

配置我们需要的属性,供配置类的使用

image-20220524003817399

配置类代码改进

  • 我们就在配置类的方法上加上@ConfigurationProperties即可,并且加上我们需要的前缀--datasource
  • @ConfigurationProperties也可以加在方法上
    • 因为@Bean注解是将被他标注的方法的返回值设置为一个组件
    • 组件相当于被IOC容器管理的对象嘛,对象的本质就是类嘛,那么我对这个类加上@ConfigurationProperties注解让他去读取配置文件的属性是没问题的吧?

image-20220524004053189

// 我这个配置类是获取数据源对象DataSource的
    @Bean
    @ConfigurationProperties(prefix = "datasource")
    public DruidDataSource getDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        // 通过set手动对某些属性进行赋值,可以随便设置,因为现在我们不需要连接数据库
        // 我们的目的是第三方Bean的属性绑定
        // dataSource.setDriverClassName("com.mysql.cj.jdbc.driver"); // 设置驱动类名,那就设置个M8的吧
        dataSource.setEnable(true); // 布尔类型的,那我设置个true吧
        return dataSource;
    }

测试结果

image-20220524004119725

一样的效果

1.5、总结

  1. 首先是关于数据源对象
    • 有些数据源对象,他是在创建的时候,内部的属性就被初始化好了
    • 而有些数据源对象,例如druid,人家创建的时候是采用懒加载的方式,只有他真正连接数据库的时候才会去处理,才会启动初始化
  2. @ConfigurationProperties,不仅可以为自己定义的组件进行属性绑定,同时也可以对第三方Bean进行属性的绑定

1.6、关于引入@ConfigurationProperties的警告

image-20220524005151886

image-20220524005213037

  • 没有配置SpringBoot对于该注解的处理器
  • image-20220524005300614
  • 加上这个即可
<!-- @ConfigurationProperties的注解处理器 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
</dependency>

2、EnableConfigurationProperties

这个注解加上了Enable,根据我看原理篇的认知,这是跟自动装配有关的,那么他跟--@ConfigurationProperties有什么关系呢?

  1. 还真有关系,我们在类上使用@ConfigurationProperties注解,说明我们这个类是一个配置类
  2. 既然是一个配置类,那么这个配置类需要被Spring管控对吧,所以他需要成为SpringIOC容器当中的组件,所以我们需要给这个配置类加上一个注解@Component
  3. 那么跟我这个@EnableConfigurationProperties有什么关系呢?还真有

2.1、主配置类的设计

  • 我们设计一个配置类吧,可以把这个配置类理解为最终的配置类,怎么个最终法?写了就知道了
  • 我们这个类做所有需要加载配置文件的类的集中配置
  • 首先这个类肯定是要被Spring管控的嘛,所以我给他写个配置注解,不然你怎么管理别人?

1、类BaseConfig的设计

  • 在这个注解的内部写上我们需要读取配置文件的类对象,该格式是数组类型的,可以写很多
/**
 * 这个类是我们的集中配置类
 * 这个类用来加载配置
 */
@Configuration
// 所有配置类我们都放在这里面进行集中的配置,可以减少我们为配置类写@Component吧
@EnableConfigurationProperties({ServletConfig.class})
public class BaseConfig {

}

2、异常产生

  1. 我们开始跑方法
  2. 发现了一个异常
  3. image-20220524231811428
    • NoUniqueBeanDefinitionException,该Bean不唯一,也就是这个组件是不唯一的,在容器当中找到了两个这样的组件
    • 因为我在ServletConfig上加上了@Component注解,他是一个组件
      • image-20220524231937046
  4. 也不是说一个类他就只能在容器当中存在一个Bean,你可以通过设置Bean的名字来创建多个同类型不同名的组件
  5. 那就说明一点,@EnableConfigurationProperties注解会把他数组当中的类对象注册为一个组件,并且注册这个组件的方式采用的是默认创建组件的方式,二者重复自然就会出现这个异常?但我刚刚测了下好像也不是啊
  6. 使用这个注解的前提
    • 被描述的类,必须加上@ConfigurationProperties注解,如果是类下的方法@Bean,然后@ConfigurationProperties然后将类定义为一个配置类@Configuration,那么也是无法被加载的,因为你是当中的方法被注册为了一个组件,并且在该方法上标注的读取配置文件
    • image-20220524232521530
    • 这样也是不行的

3、问题的引出--松散绑定

如果命名规范的话,我们yml当中配置的测试数据源信息,dataSource应该采用驼峰命名法

image-20220524232641484

但是当引用的时候,这里就报错了,这是为什么呢?

image-20220524232752379

小写的能用,大写的不行,为啥呢

image-20220524232832814

3、宽松绑定or松散绑定

3.1、概述

  • 对于我们使用@ConfigurationProperties这个注解的时候,他绑定属性,对于这个名称上的要求是非常灵活的,SpringBoot的开发者为了兼顾大多数编程爱好者的书写习惯,设置了若干种匹配格式

image-20220524232921328

1、什么是松散绑定?

  1. 用我们最开始的demo举例子,在ServletConfig类中,我们对yml文件进行了读取配置
  2. 其中以ipAddress举例,我们这个变量是和配置文件当中的变量对应的对吧,完全对应
  3. image-20220524233907052
  4. 但是这样写也可以形成对应,我就不测试了
    • image-20220524233733770
  5. 为什么呢?其实就是内部采用的松散绑定的形式,只要配置类和配置文件相对的配置的,字母是一致的,无论加上下划线,中划线,随意大小写,都是可以识别到的,只要二者小写字母是一致的
  6. 在上述途中,例举一下常用的几种yml文件变量的写法
    • 驼峰命名法:ipAddress
    • unline模式:ip_address
    • 串模式:ip-address
    • 常量写法:IP_ADDRESS
  7. 这些写法在spring的开发当中都能大量看到,不过更主张使用串模式的开发方式

当我们使用@ConfigurationProperties拉绑定属性的时候,它的名称比较随意,松散,可以支持很多种形式

image-20220524234335769

注意:不是所有注解都支持这种形式的,例如@Value就不行

image-20220524234510766

这也是Boot让我们主推的方式---@ConfigurationProperties

2、之前问题的解答,为什么prefix当中使用驼峰不可以

  1. 我们来看下这个异常
  2. image-20220524234935543
  3. 啥意思?
    • 就是你用来接收配置文件的名称定义是什么样的?
  4. 这也是跟松散绑定相关的知识,所以以后遇到这种问题,二话不说直接全部小写即可
  5. 或者剑走偏锋我就要试试中划线,我来试试
    • image-20220524235153673
    • image-20220524235205364
  6. 嘿嘿~

3、总结

image-20220524235331504

4、问题引出

  • timeout在我们这里配置的是超时时间,-1代表用不超时,这样写肯定是不行的,但是如果我想给他设置的超时时间是多少分钟?、多少秒、多少小时?这些应该怎么设置?
  • 如果设置的是毫秒,或者分钟,就像下图这样,那么读起来会不会有阅读障碍?
  • 有什么方法可以解决嘛?必须有,在JDK1.8中提供了两种数据类型用来解决这类问题

image-20220524235546917

4、常用计量单位应用

4.1、概述

  1. 上节我们说到关于计量单位的问题,我们之前的yml配置当中,timeout为-1是可以被识别到的,你写其他的也行,例如3、4、5、6、7、8、9啊,等等
  2. 但是当我写这些数据的时候,例如3,我这是3毫秒呢?还是三秒钟呢?还是三分钟呢?亦或者是三小时?这就说不清了吧?或许根据业务需求,可以对常量进行内部的规划,但,在旁人眼里看来呢?别人不清楚啊,--这种数据类型的描述方式就会出现一些误解
  3. 在我们JDK8版本中,对于数据类型,如果是Long型的话,那几本就可以确定--该数据类型是一个毫秒类型的
  4. 在JDK8以后,出现了一系列与单位有关的数据类型,其中有一个数据类型是 --Duration

4.2、Duration

1、概述

参考文档--Duration引用

  1. JDK8版本后推出的一种数据类型,主要用于计算时间日期,差值之类的
  2. 该数据类型可以指定时间类型,如果不指定时间类型默认是秒--S
  3. 可以指定的时间类型有很多
    • image-20220526005007904
  4. 该数据类型的共用方法
    • 时间转换为时分秒:toSeconds(),to…()等方法
    • 两个Duration比较:compareTo()相等返回0,大于返回正数,小于返回负数
    • 获取指定单位的数值:get(TemporalUnit unit)
    • 获取Duration中所有单位:getUnits()
    • 获取Duration绝对值:abs()
    • 给指定Temporal添加一个Duration:addTo(Temporal temporal)
    • getNano() 获取纳秒数,获取的是纳秒部分的值,而不是转换成纳秒
    • getSeconds() 获取秒数,获取的是秒部分的值,而不是转换成秒
    • plusSeconds(), plus…() 加法 增加时间(时分秒),返回新实例
    • dividedBy(long divisor) 除法,返回一个新的Duration实例,内部转换成秒来实现
    • multipliedBy(long multiplicand) 惩罚,返回一个新的Duration实例,内部同样也是转换成秒来实现
    • minus…()相关方法 减法:注意是用你输入参数去减,返回的是新的Duration实例
    • 四则运算都是返回的新实例,并没有对旧实例进行修改,这是需要注意的,所以千万别忽略了返回值。
    • 返回一个负的Duration实例:negated() 比如 PT1.4S 返回 PT-1.4S
    • isZero() 判断是否是 ZERO 实例
    • withSeconds() 和 withNanos() 两个方法通过传入秒数或者纳秒数来构造一个Duration副本

2、新增属性区分默认和设置类型

image-20220526004127471

/**
 * 这是一个配置类,这个配置类会加载yml文件当中我们所需要的配置
 */
// @Component("cinfigurat") // 你要加载SpringBoot的yml文件,那么你自己得是一个被SpringBoot所管控的容器
@Data
@ConfigurationProperties(prefix = "servers")
public class ServletConfig {
    /**
     * 通过 @ConfigurationProperties,配置了前缀我可以读取到当中的配置
     * @Param ipAddress IP地址
     * @Param port IP地址的端口号
     * @Param  timeout IP地址的超时时间
     */
    private String ipAddress;
    private int port;
    private int timeouts;
    // JDK8版本之后推出的数据类型,多用于时间日期,差值计算
    @DurationUnit(ChronoUnit.DAYS) // 该注解可以指定需要的时间类型
    private Duration serversTimeOut; // 服务器超时时间类型

    // 我这里写一个默认的Duration类型的值,等会会一起打印
    private Duration defaultDuration;
}

3、yml文件配置

image-20220526004221345

servers:
  ipAddress: 172.16.1.1
  port: 8080
  timeout: -1
  servers-timeout: 5
  default-duration: 3

4、打印输出

  • 这里我们可以看到,没有设置时间类型的话默认是秒
  • 如果设置的时间超过小时的话,例如天,那么会转换为小时的样式

image-20220526004243319

5、报错分析

  1. 我这里将事件设置为了weeks,也就是多少周,爆了这么一个错误
    • image-20220526004421877
    • image-20220526004452624
  2. failed to convert java.lang.Integer to @org.springframework.boot.convert.DurationUnit java.time.Duration (caused by java.lang.IllegalArgumentException: Unknown unit Years)
    • image-20220526004403445

4.3、DataSize

1、概述

  1. 这个变量是配置存储容量的,说简单点就是存储空间的大小
  2. datasize,数据的大小,默认单位是Byte,也就是比特
  3. 如果是读取配置文件的话,那么可以在配置文件当中写MB,KB,GB,TB等单位来描述
  4. 也可以通过指定该DataSize类型来指定存储空间的大小
    • image-20220526005853085

2、yml文件配置

image-20220526005352881

3、类的属性添加

image-20220526005630754

/**
 * 这是一个配置类,这个配置类会加载yml文件当中我们所需要的配置
 */
// @Component("cinfigurat") // 你要加载SpringBoot的yml文件,那么你自己得是一个被SpringBoot所管控的容器
@Data
@ConfigurationProperties(prefix = "servers")
public class ServletConfig {
    private String ipAddress;
    private int port;
    private int timeouts;
    // JDK8版本之后推出的数据类型,多用于时间日期,差值计算
    @DurationUnit(ChronoUnit.DAYS) // 该注解可以指定需要的时间类型
    private Duration serversTimeOut; // 服务器超时时间类型
    // 我这里写一个默认的Duration类型的值,等会会一起打印
    private Duration defaultDuration;

    // 内存空间大小描述--DataSize
    // 默认描述
    private DataSize serversDataSizeDefault;
    // 在配置文件当中指定描述
    private DataSize serversDataSizeOne;
    // 通过注解指定内存大小的类型,这里指定为MB
    @DataSizeUnit(DataUnit.MEGABYTES)
    private DataSize serversDataSizeTow;
}

4、测试

image-20220526005839302

是没问题的

5、Bean的属性校验

5.1、概述

如果Bean当中的属性能够做校验,那么就可以有效的帮我们做数据安全性的保障了

  1. 对于数据校验来说,他实际上是各个业务系统中,必不可少的一个环节
  2. 不管你是什么样的数据,总之在进行使用之前,做一套有效的数据校验,做一套配置也、好业务数据也好、具有很强的安全性,不至于出现预料之外的错误
  3. 对于这个数据校验的功能,是一个新功能吗?--不是的
  4. Java2EE规范了一套数据校验的API,我们只需要使用即可
  5. image-20220526010604736

5.2、使用校验框架

1、导入框架依赖

在pom.xml当中引入相关依赖,他是一个接口,而非实现类,是一套标准的校验框架

image-20220526011051117

<!-- 数据类型校验框架-JSR303 -->
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
        </dependency>

image-20220526011206908

在SpringBoot的版本管理当中默认使用的是2.0.1.Final

2、在什么地方使用?

导入依赖后,想让哪儿有校验的功能,在哪儿开启校验的功能?

开启对当前Bean属性注入的校验

image-20220526011548692

配置我们的校验规则

  • 例如MaxMin注解,最大or最小
  • 该注解是属于 javax.validation.constraints下的,别用错了

image-20220529125159923

image-20220529125308978

代码

/**
 * 这是一个配置类,这个配置类会加载yml文件当中我们所需要的配置
 */
@Data
@ConfigurationProperties(prefix = "servers")
@Validated // 2、开启对当前Bean的属性注入的校验
public class ServletConfig {
    /**
     * 通过 @ConfigurationProperties,配置了前缀我可以读取到当中的配置
     * @Param ipAddress IP地址
     * @Param port IP地址的端口号
     * @Param  timeout IP地址的超时时间
     */
    private String ipAddress;
    // 3、配置校验规则,端口号不能超过8888
    @Max(value = 8888,message="端口号最大不能够超过8888!")
    @Min(value = 5000,message="端口号最小不能低于5000!")
    private int port;
    private int timeouts;

}

3、小小测试一波(报错原因)

  1. 在我们测试的时候出现了这么一个异常
  2. The Bean Validation API is on the classpath but no implementation could be found
  3. 这个Bean组件,校验APIValidation)在我们的类路径下没有实现类,或者说,它的实现类不能被发现
  4. 接口给你了,得有实现类

image-20220529125548724

4、配置校验规则

  1. 第二步我只是对这个Bean开启了校验功能,但是怎么校验,如何校验,那就需要我们自行配置了
  2. 接口给你了,得有实现类
  • 就像你用Servlet对应谁实现的?TomCat实现的
  • 使用JDBC连接Mysql对应是谁实现的? JDBC是接口,Mysql驱动才是实现类
  • 我现在要使用校验框架,是谁实现的?没有实现类,得我们自己来
    • 继续看报错
    • 例如Hibernate校验器,将其添加到类路径中
    • image-20220529125842350

5、Hibernat

  1. Hibernat是一个校验引擎,我们需要让Hibernat作为我们校验框架Validation)的实现类
  2. 在pom文件引入对应依赖
  3. image-20220529130333836
  4. 使用Hibernate框架提供的校验器实现类
<!-- Hibernate校验引擎,使用Hibernate框架提供的校验器做实现类 -->
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
</dependency>

关系理解

  • 他俩的关系可以这么理解
    • 上面是jdbc,下面是mysql驱动
    • 上面servlet,下面是tomcat
    • 那么上面是我们的校验框架(Validation),那么下面就是咱们这个校验框架的实现类(Hibernate

image-20220529131001052

6、再次运行

  • 当我们再次运行的时候,确实是成功运行了
    • image-20220529131618420
  • 那么我们将端口号的值重新配置超过我们约定范围的值--Max
    • image-20220529131639147
    • image-20220529131703301
  • 在我们这个配置类(ServletConfig)绑定属性(properties)的发生的绑定异常,下面是提示内容

7、关于校验框架

  1. 对于这个校验框架的讲解还只是一个比较片面的理解,实际开发的时候,这个校验框架的作用是非常大的
  2. 这期篇幅有限,所以就暂时说这么多
  3. 最后一个,当我们点进这个@Max注解当中的时候,我们看下别人的包
    • image-20220529132434106
    • image-20220529132445227
  4. 这里是有非常多的注解供我们使用的

8、总结

  1. 使用校验框架和校验框架的实现
  2. 在需要校验的地方添加上@Validated,开启校验框架的功能
  3. 详细配置我们的校验规则

image-20220529132607007

6、进制数的转换

6.1、问题回顾

  1. 我记得我刚刚开始使用SpringBoot的时候,有一天在做到SpringBoot整合第三方技术的时候
  2. 我刚好在那天学习到整合Mybatis,做Web项目嘛,不连数据库怎么行?
  3. 在yml配置文件当中配置数据源--datasource的时候,我遇见了一个问题
    • 我个人有做笔记的习惯嘛,我喜欢写一步做一步,在那天这个错误的信息被我留存下来了
    • image-20220529133843980
  4. 这就是我当时配置数据源的配置,我遇到了一个问题,我死活都连不上数据库
    • 我通过cmd终端连接我的数据库,没问题
    • 通过图形界面化工具Navicat连接也没问题
    • 但是就是使用SpringBoot配置我的数据库连接的时候,连不上,密码是错的
  5. 我很郁闷,但是那天我也找到了问题的所在,只是我不明白为什么会出现这个问题

6.2、问题复盘

  1. 将原先的demo给大家来复个盘
    • image-20220529134718689
    • 这是咱的yml配置文件,我现在将它(password)设置为int类型
    • 同时,这里有个实体test,我让他来读取我这个配置文件当中的值
    • image-20220529143222539
  2. 接下来,咱们开始打印输出测试一下结果,看看发生了什么事情?
    • image-20220529134951952
  3. 我明明写的是 010115,为什么打印出来是4173呢?

6.3、问题出现的原因

上述这种情况,其实任何开发人员都有可能遇见的,所以这里需要提一下

  • 在我们学习yaml语法规则的时候
  • 信息量不大,但是有几个信息容易忽略
  • int值支持,二进制,八进制,十六进制
    • 二进制是什么:0b1010_0111_1010_1110,这种类型的
    • 八进制的语法:以0开头,后面跟上(0-7)=>0 (0-7)=>0(10115)
    • 十六进制呢:0x开,(0-9,a-f)跟

image-20220529140751183

我们打开计算器,测试一下,为什么010115 会变成 4173呢?

image-20220529142827507

  • 现在明白了吧,我的密码刚好是以0开头的,然后又恰好后面的数字都只包含0-7,他是一个标准的八进制,才会在八转十的时候遇见这个问题
  • 只能说太倒霉加上太巧了,但凡密码不是以0开头的都不至于这样,当然,如果是0x开的那遇到了也没辙对吧
  • 那么他的隐藏性主要在哪里

6.4、问题的隐藏性

  • 我们后台接受数据的时候,password是按照字符串来接收的
  • 他识别到了0开的数据(0(010115))以后,并且又是一个纯数字,他默认把它按照数值进行解析=>八进制转十进制
  • 转换完毕得到结果了=>4175,那直接将其转换为字符串即可,从而注入到我们的实体类配置项当中
  • 最终就出现了我们这么一个问题

6.5、总结

  • 像我们这个问题最终引发的后果就是,连不上数据库,其实和连数据库有关系吗?没有关系?
  • 就是因为这个地方的格式转化问题,你能赖别人吗?
    • image-20220529143811595
  • 人家SpringBoot都推荐了,如果是纯数字结构的,那么你用字符串给他包上就行了
  • 我们这里
    • 恰巧没用字符串包上、
    • 恰巧又刚好是一个八进制,这个八进制被转换成十进制了、
    • 恰巧,转化出来的密码又刚好可以和String类型时配上、
    • 恰巧,转化出来的十进制密码跟你数据库当中的密码完全不一样、
    • 恰巧,你连不上数据库
posted @   澜璨  阅读(122)  评论(0编辑  收藏  举报
编辑推荐:
· 如何在 .NET 中 使用 ANTLR4
· 后端思维之高并发处理方案
· 理解Rust引用及其生命周期标识(下)
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
阅读排行:
· Cursor预测程序员行业倒计时:CTO应做好50%裁员计划
· 想让你多爱自己一些的开源计时器
· 大模型 Token 究竟是啥:图解大模型Token
· 用99元买的服务器搭一套CI/CD系统
· 当职场成战场:降职、阴谋与一场硬碰硬的抗争

喜欢请打赏

扫描二维码打赏

了解更多

点击右上角即可分享
微信分享提示