1 背景
系统启动或者运行过程中,经常会读取或者解析一些物理文件,诸如以下场景:
-
密钥文件:支付密钥、接口密钥等
-
简易数据文件:xdb、csv、json等数据文件
-
配置文件:xml、Properties等文件
这些文件,有些是在启动中必须用到的,有些则是在运行时使用的。
其中启动时必须用到的文件,在打包或者部署时,大概率是有相应的验证机制的,此时文件缺失带来的是系统无法启动的直接结果,工程师可以直观的进行问题定位处理,响应相对及时;
运行时使用到的文件可能存在非强制验证的情况,该情况下,文件的缺失不影响项目的启动,而项目运行过程中,缺失文件可能导致客户端使用报错,从而导致生产事故。
针对以上的情形,业务设计和实现过程中,需要对核心文件(关键路径)进行核查,以便提前发现生产问题。
下面我们基于核心文件校验的目标进行组件设计。
2 常用解决方案
2.1 方案说明
针对文件存在校验的需求,常见的处理方式一般存在两种方式,分别为:
-
开发人员在业务实现时自己写文件校验
-
统一文件校验实现类,业务人员在业务实现时,将需要检验的地址,配置到统一的待校验文件列表中
下面我们针对以上两种方式进行案例说明
2.2 方案实现实例
-
各自业务内实现文件校验
以支付宝支付为样例,支付过程中需要使用支付宝提供的公钥和私钥文件,并且此类文件不建议打包进jar包中。
public class PayService{
// 私钥文件地址
@Value("${alipay.private-key-path:}")
private String privateKeyPath;
// 公钥文件地址
@Value("${alipay.public-key-path:}")
private String publicKeyPath;
private AlipayClient alipayClient;
@PostConstruct
public void init() {
// *******************根据文件地址校验文件是否存在 开始********************
if (!new File(privateKeyPath).exists() || !new File(publicKeyPath).exists()) {
throw new Exception("支付宝密钥文件不存在,请查验");
}
// *******************根据文件地址校验文件是否存在 结束********************
// 根据私钥和公钥文件路径,读取密钥信息
String privateKey = FileUtil.readUtf8String(privateKeyPath);
String publicKey = FileUtil.readUtf8String(publicKeyPath);
if (StringUtils.isEmpty(privateKey) || StringUtils.isEmpty(publicKey)) {
log.error("支付密钥/公钥不存在");
throw new Exception("启动失败,支付宝支付密钥或者私钥异常!");
}
// 初始化客户端
// alipayClient = new DefaultAlipayClient(..........);
}
// *************************唤起支付**************************
public String wakeupPay(){
// **************唤起支付,需要用到密钥***************
}
}
上述方式,文件的校验由工程师开发时自己实现

-
统一文件校验
还是以支付宝支付流程为例,将文件校验的步骤抽调出来统一进行校验。
支付实现(去除文件校验)
public class PayService{
// 私钥文件地址
@Value("${alipay.private-key-path:}")
private String privateKeyPath;
// 公钥文件地址
@Value("${alipay.public-key-path:}")
private String publicKeyPath;
private AlipayClient alipayClient;
@PostConstruct
public void init() {
// 根据私钥和公钥文件路径,读取密钥信息
String privateKey = FileUtil.readUtf8String(privateKeyPath);
String publicKey = FileUtil.readUtf8String(publicKeyPath);
if (StringUtils.isEmpty(privateKey) || StringUtils.isEmpty(publicKey)) {
log.error("支付密钥/公钥不存在");
throw new Exception("启动失败,支付宝支付密钥或者私钥异常!");
}
// 初始化客户端
// alipayClient = new DefaultAlipayClient(..........);
}
// *************************唤起支付**************************
public String wakeupPay(){
// **************唤起支付,需要用到密钥***************
}
}
文件统一校验
public class FileExitCheck{
@Value("${check.file.list:}")
private

1301

被折叠的 条评论
为什么被折叠?



