【项目设计技巧】客户端SDK的开发
大家好,我是仰望-星空~~,好久不见,我的文章都断更快一个月了(😅),这段时间我一直在做新的项目,然后考驾照的事情也是让我心烦不已,连学校的课都落下不少,主要还是做项目对我更加有吸引力。话不多说,进入今天的正题。。。。
一、问题引入
关于SDK相信大家都用过,我们创建项目时导入的依赖包就是一个SDK,我们能够调用依赖中提供的方法,就是因为别人已经将现成的代码方法封装好了,我们只需要调用就行。
那为什么要使用引入SDK的方式来调用我们所需要的方法呢?
自然是为了我们的代码更加的便于维护,和我们平时封装一段通用的逻辑代码一样,就是为了它更加简洁美观和便于维护。在一个项目中我们通过一个通用的SDK,让各个子系统进行引用,这样就可减少大量的重复代码工作,提高开发效率。
二、方案提出
那这里就有个问题了,什么是我们通用的代码逻辑呢?什么可以封装在一个SDK中进行调用呢?
需要从开发者的角度来考虑,对于我们的这个项目来说
难道开发者每次调用接口都需要自己写签名算法吗?
开发者只需要关心密钥\ak是什么,具体怎么生成随机数和签名他们是不需要关心的
所以我们需要开发 SDK,开发者只需要关心调用那些接口,传递哪些参数
开发 starter 的好处:开发者引入后,可以直接在 application.yml 中写配置,自动创建客户端
上一篇文章,我介绍了关于API签名认证【业务场景实战】API签名认证-CSDN博客的相关知识,这篇文章我同样以上一篇文章为基础,介绍如何使用SDK进行代码的优化设计。
三、代码实现
上一篇文章关于API签名认证,我们使用了客户端类moonClient 、签名工具类SignUtil来进行签名生成。
这里我们创建一个ClinetSDK子项目
1、依赖的修改
这里改一下ClinetSDK子项目的版本号,其实不改也行,只是为了引入依赖的时候更加方便
删除这段依赖
2、依赖的添加
hutool依赖是为了方便之前的签名工具类的添加
上一个依赖的作用:自动生成配置的代码提示,这个依赖很重要
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<!--hutool工具类-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
3、配置
1)包的移动
将客户端类moonClient 、签名工具类SignUtil和模拟接口中的请求参数实体类都加入ClinetSDK子项目中。修改 客户端类 MoonClient 类的代码,把web注解都删除
这是最后的项目结构图
2)配置类创建
删除主类,将配置类放于最外层包——代替启动类的位置
这段代码的作用是创建一个名为moonClient
的Spring Bean,它是一个MoonClient
类型的对象。这个对象在创建时会使用accessKey
和secretKey
作为参数进行初始化。这样,当其他地方需要使用MoonClient
时,可以通过注入moonClient
这个Bean来获取已经初始化好的MoonClient
实例。
@Data
@Configuration
@ConfigurationProperties("moon.client")
@ComponentScan
public class MoonClientConfig {
private String accessKey;
private String secretKey;
@Bean
public MoonClient moonClient(){
return new MoonClient(accessKey,secretKey);
}
}
其实这种代码应该不陌生,例如我们在使用Redisson配置的时候,除了需要在配置文件中引入相应的连接信息之外,还需要创建配置类,让其配置的参数通过配置类进行初始化,这样我们调用客户端的时候就会自动携带我们所配置的参数。
配置好以后,springBoot 会自动给我们创建一个Moonclient 对象,我们就可以调用了
3)自动配置
虽然我们现在使用了MoonClientConfig客户端配置类,但我们的配置依然不会生效,我们需要让springboot自动识别到我们的配置
META-INF/spring.factories
文件是 Spring 框架中用于配置和扩展机制的重要文件。它允许开发者在不修改现有代码的情况下,通过配置文件来注册自定义的组件、自动配置类和其他扩展点。
创建一个目录 META-INF
,目录下新建一个文件 spring.factories
我们需要将配置类 MoonClientConfig
类设置为自动配置类,让springboot 能自动识别
org 会有提示,复制配置类路径
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.MoonClientConfig
4、打包
我们对已经写好的依赖进行打包,执行 install,这时可能会报错,打包失败
需要将测试类删除或者过滤掉测试
如果打包出现bug,看看是不是这个问题
编译打包小bug:
install失败不再支持源选项 5。请使用 7 或更高版本。
其实在maven里的conf的setting.xml中已经写清楚了:(这里是jdk1.4了)所以如果不配可能就是默认低版本的
我们需要在settings.xml文件中指定jdk版本
加上这段配置
<profiles>
<profile>
<id>jdk-18</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
5、测试
1)删包
回到 Interface 项目,把原先的三个包(实体类、客户端、工具类)删除,
2)导入 SDK依赖
在新的子项目中导入我们的子项目ClientSDK依赖
<!--导入我们的SDK依赖-->
<dependency>
<groupId>com.example</groupId>
<artifactId>ClientSDK</artifactId>
<version>0.0.1</version>
</dependency>
创建的 SDK 在我们本地的Maven 仓库下,只能在我们自己的电脑上使用,如果想让别人也用到你的SDK,可以发布到Maven官网的仓库上。哥也没试过,我也不会
把所有的原来的包引入的都修改成 SDK包引入
3)配置文件引入
我们导入SDK包之后,编写相应的配置,正常来说,如果前面的操作都OK,这里会出现提示,就像正常的依赖一样
moon:
client:
access-key: moon
secret-key: abcdefg
4)测试
我们客户端里面提供了三个方法,这里我们只看`getNameByBody`这个方法,这个方法是我们最常用的RESTful形式的接口
调用流程:
- 我们第一步在yml配置文件中导入相关的客户端配置
- 第二步,注入了moonclient客户端,项目启动时,配置会生效,对客户端Bean进行初始化
- 第三步,调用客户端方法,并通过User参数实体类传入相关的参数
- 后续的内部操作签名生成、校验就不需要开发者去关心了
@Resource
private MoonClient moonClient;
/**
* SDK 客户端依赖引入
*/
@Test
void SDKTest(){
User user=new User();
user.setUsername("moon03");
String result03 = moonClient.getNameByBody(user);
System.out.println(result03);
}
测试成功
5)签名认证流程
这里可能有不少兄弟可能会一脸懵逼,这很正常。如果我没看上一篇文章,不知道这个调用流程可能也不知道这里为什么就调用成功了,写的aksk配置都不知道到底有没有生效?
这是整个调用客户端SDK实现签名认证的流程
1、首先我们导入客户端SDK
这个SDK里面封装了用户实体类、api接口的客户端、签名生成工具
2、配置属性as\sk写入其他子项目
3、调用方法
1)使用moonClient调用其中的方法,传入我设置的用户信息
客户端MoonClient 内将用户信息和ak、时间戳、随机数和签名一起放在hashmap参数集合中。签名sign通过用户信息和sk密钥在签名生成工具类中生成签名sign
2)最后在实际请求中将hashmap放入请求头中传递给controller层,在controller层中进行校验,获取到数据库中登录用户的ak\sk,然后和我配置文件中写入的ak进行比较
3)将数据库中的sk和我传入的用户信息也进行签名生成serverSign
4)然后将两个签名进行比对,如果一致,那么接口就可以被调用。
到这里我们的客户端SDK开发就完成了,其实也挺简单的!各位有兴趣也可以开发一个自己的SDK试试。
今天我们的分享就到这里,欢迎喜欢我文章的兄弟点赞、评论、关注,更多优质内容和你分享~~~