探究对接支付API时,相遇获取文件的绝对路径
问题概述?
最近呢在公司做项目对接了某宝的支付转账功能,不过现在对接确实比之前方便了好多,可以直接引用SDK的Maven依赖的方式,然后再根据官方文档的Demo拿过来直接就可以使用,但是呢,需求是可能后面陆续会有多个APPID账号来发起支付操作,所以代码就不能写的太死板,思量了一番之后决定可以使用策略+模板方法 + BeanFactory工厂等组合设计模式。
为啥使用(策略+模板方法 + BeanFactory)?
首先通过分析接口文档,对于开发者来说就是一个,就是只是存在付款主体不同而已,其他请求接口照旧执行,但是总不能每次新增一个付款主体,都改下原来的接口或者就是通过If条件句来判断,这种实行起来虽然可以,就是太low了,想要代码高大上而且效率高,就需要提升代码编码能力,且还需满足高内聚、低耦合以及开闭原则(开:扩展性开放;闭:修改关闭)。
步入主题
- 代码如下:
tring privateKey = "<-- 请填写您的应用私钥,例如:MIIEvQIBADANB ... ... -->";
CertAlipayRequest alipayConfig = new CertAlipayRequest();
alipayConfig.setPrivateKey(privateKey);
alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
alipayConfig.setAppId("<-- 请填写您的AppId,例如:2019091767145019 -->");
alipayConfig.setCharset("UTF8");
alipayConfig.setSignType("RSA2");
alipayConfig.setEncryptor("");
alipayConfig.setFormat("json");
alipayConfig.setCertContent("<-- 请填写您的应用公钥证书内容字符串 -->");
alipayConfig.setAlipayPublicCertContent("<-- 请填写您的支付宝公钥证书内容字符串 -->");
alipayConfig.setRootCertContent("<-- 请填写您的支付宝根证书内容字符串 -->");
AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
看上边代码有什么想说的(没啥说的其实,准备好请求参数直接调用API就完事了),然而该接口要求必须采用公钥证书模式进行加签,所以就引出了我写这篇文档的由来(获取文件的绝对路径)。
项目中获取文件的绝对路径可采用如下方式:
- 以类加载方式
// 获取绝对路径
String absolutePath = this.getClass().getResource("/").getPath();
String certAbsolutePath = absolutePath + "/alipayRootCert.crt";
alipayConfig.setRootCertContent(certAbsolutePath);//咦,本地运行通过咯,binggou完事 ,唉 这么简单?继续往下看哦
- 以ClassPathResource方式
// 获取绝对路径
String certAbsolutePath = new ClassPathResource("/wsy/alipayRootCert.crt").getFile().getAbsolutePath();//咦,本地运行通过咯,但是 linux服务器上不行 会报java.io.FileNotFoundException
// 哈哈嗨 一直都是本地可以 linux服务器上就跑不起来么,看来还得找解决方案
- 错误日志贴上
[支付宝CA根证书文件路径加载失败!] 失败原因:class path resource [wsy/alipayRootCert.crt] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/data/project/and url/tc-gateway-alipay.jar!/alipayRootCert.crt
- 原因:
在项目构建的时候Maven插件会把resource下的文件copy过去之后,然后再打成jar包(通过JUI反编译之后文件是存在的),但绝对路径无法获取。
- 解决方案
因此可以考虑在当前项目下创建一个文件夹,然后加载Jar中的resource资源,以InputStream流写入创建好的文件路径(Apache 下的FileUtils.copyToFile(final InputStream source, final File destination)),然后再获取file的绝对路径,此时该文件在服务器是如实存在的,代码如下:
// 支付宝CA根证书文件路径
try {
// TODO获取当前项目环境路径
String sysAbsPath = System.getProperty("user.dir");
// 获取资源流
ClassPathResource resource = new ClassPathResource("/alipayRootCert.crt");
// 根据绝对路径 创建File
File aliPayRkFile = new File(sysAbsPath + "/alipayRootCert.crt");
// 将InputSteam写入File中
FileUtils.copyToFile(resource.getInputStream(), aliPayRkFile);
// 最后再获取文件的绝对路径
this.aliPayRootCrtAbsolutePath = aliPayRkFile.getAbsolutePath();
log.info("支付宝CA根证书文件加载完毕 路径:{}", aliPayRootCrtAbsolutePath);
} catch (Exception e) {
log.error("[支付宝CA根证书文件路径加载失败!] 失败原因:{}", e.getMessage());
}
- 针对探究问题进行总结
对于Jar中文件资源,想要获取Jar中文件的绝对路径,需先在(Windows|Linux)创建一份,相当于Copy,然后就能得到文件的绝对路径。
聊下用到的设计模式
- 策略+模板方法 + BeanFactory
- 结合Spring 自定义策略Bean
- 模板方法 进行抽象剥离 以及实现
- BeanFactory工程,AlipayClient由Spring进行管理
ENDING
你能看到此处,说明咱们遇到了相同的问题,上边就是问题提的解决方案,希望对你有所帮助,同时也帮忙进行点赞和转发哦!3Q
Come 的喂, ABC! 哈哈哈