“ Yuema约吗?一起学技术,一起成长!学海无涯 高人带路系列”
程序的世界,就是有坑的地方!分享踩坑的心得与体验!每天分享一点点!
关注公众号,进入学海无涯,高人带路模式!!
支付再难,有人带路,轻松搞定
每次看动漫看美剧,都有狗血的前情回顾,占了好长的时间,有种说不同的酸痛感!腰疼!
想不到,我也活成了自己讨厌的人,我也要写个前情回顾
前情回顾
上回讲到接阿里蚂蚁金服支付宝网银直连的整体代码结构,提到封装了一个alipay-bankpay-sdk,并画了2个对比图,介绍了一下这么干的好处,代码清晰,通用性强。按文章的条理来讲,您应该先看上篇,再来看这篇。
关注Yuema约吗公众号,回复”bankpay”,查看《支付宝网银直连SDK封装记上|强力去掉支付宝网银直连DEMO中56个坏味道 余下6个坏味道 Sonarqube无视阿里支付宝光环》
本文向导
本文主要分享一下封装支付宝网银直连sdk的思路、坏味道清理,并做个小小的总结。完整的看完本文,您应该学会一种取巧的sdk封装思路并能运行于实战,并且能看到一些更加简洁的代码写法,并能学会如何从BTA中学东西,并从中剔除不良习惯。
封装思路
虽然阿里支付宝的程序员在代码中明确表明给出来的demo仅供参考blabla的。但是整体上来讲,封装sdk还是主要使用他们的demo,从作为sdk的角度对代码进行细微调整。
/* *
*类名:AlipaySubmit
*功能:支付宝各接口请求提交类
*详细:构造支付宝各接口表单HTML文本,获取远程HTTP数据
*版本:3.3
*日期:2012-08-13
*说明:
*以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
*该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
*/
封装思路一
做为sdk,我去掉了demo中的AlipayConfig.java,因为不同的项目所使用到的商户号、密钥等都不相同,放在sdk中,不妥当。去掉AlipayConfig.java后,其他的代码要相应的调整一下。我们将配置以参数的形式,传递进去。这样子确保,我们能通过其他方式配置网银直连所需的商户信息。我采用了这种思路,很简单很傻瓜式的调整一下。
封装思路二
可以参考最新的支付宝sdk的封装方式,抽象一个AlipayClient出来,初始化的时候,把AlipayConfig.java的工作做了。我没有使用这种思路,但是感觉这是一种不错的思路。调整稍微大点。
坏味道清理
程序的世界可以说很大很大,咱们就像盲人摸象。坏味道清理是将代码中不规范不合理的地方进行调整。通过使用sonarqube对阿里的网银直连demo进行扫描,发现了56个坏味道,还有1个bug,1个漏洞。
坏味道1:命名空间不规范
支付宝
com.alipay.util.httpClient
com.alipay.util.httpclient
坏味道2:冗余写法,不够简洁
Replace the type specification in this constructor call with the diamond operator ("<>"). (sonar.java.source not set. Assuming 7 or greater.)
List<String> keys = new ArrayList<String>(sPara.keySet());
List<String> keys = new ArrayList<>(sPara.keySet());
坏味道3:多余的转化
String name = (String) keys.get(i);
Remove this unnecessary cast to "String".
坏味道4:直接返回即可
String strResult = response.getStringResult(charset);
return strResult;
Immediately return this expression instead of assigning it to the temporary variable "strResult".
坏味道5:这里不要线程安全
Replace the synchronized class "StringBuffer" by an unsynchronized one such as "StringBuilder".
StringBuffer result = new StringBuffer();
坏味道6:静态类不要初始化
Add a private constructor to hide the implicit public one.
坏味道7:一行代码搞定
修改前:
if (isSign && responseTxt.equals("true")) {
return true;
} else {
return false;
}
Replace this if-then-else statement by a single return statement.
修正后:
return isSign && responseTxt.equals("true");
坏味道8:局部变量命名不规范
input_charset
Rename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.
坏味道9:static final变量命名不规范
public static final String dtLong = "yyyyMMddHHmmss";
Rename this constant name to match the regular expression '^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$'.
坏味道10:参数不符合规范
Rename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.
private static boolean getSignVeryfy(Map<String, String> Params, String sign,String signType,String key,String charset)
坏味道11:局部变量命名不符合规范
String veryfy_url = HTTPS_VERIFY_URL + "partner=" + partner + "¬ify_id=" + notify_id;
Rename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.
坏味道12:多此一举
inputLine = in.readLine().toString();
"readLine" returns a string, there's no need to call "toString()".
坏味道13:一行代码搞定
Replace this if-then-else statement by a single return statement.
if(mysign.equals(sign)) {
Replace this if-then-else statement by a single return statement.
clumsy
return true;
}
else {
return false;
}
坏味道14:局部变量命名不规范
Rename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.
private static String verifyResponse(String notify_id,String partner)
坏味道15:抛异常不规范
public static String query_timestamp(String partner,String charset) throws MalformedURLException, DocumentException, IOException
Remove the declaration of thrown exception 'java.net.MalformedURLException' which is a subclass of 'java.io.IOException'.
坏味道16:Use a StringBuilder instead
Use a StringBuilder instead.
StringBuilder prestr = new StringBuilder();
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
String value = params.get(key);
if (i == keys.size() - 1) {//拼接时,不包括最后一个&字符
prestr.append(key + "=" + value);
} else {
prestr.append(key + "=" + value + "&");
}
}
return prestr.toString();
String prestr = "";
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
String value = params.get(key);
if (i == keys.size() - 1) {//拼接时,不包括最后一个&字符
prestr = prestr + key + "=" + value;
} else {
prestr = prestr + key + "=" + value + "&";
}
}
return prestr;
坏味道17:不规范的变量命名
private static String DEFAULT_CHARSET = "GBK";
Rename this field "DEFAULT_CHARSET" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.
private static final String DEFAULT_CHARSET = "GBK";
坏味道18:不规范的变量命名
/** 默认等待HttpConnectionManager返回连接超时(只有在达到最大连接数时起作用):1秒*/
private static final long defaultHttpConnectionManagerTimeout = 3 * 1000L;
Rename this constant name to match the regular expression '^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$'.
private static final long DEFAULT_HTTP_CONNECTION_MANAGER_TIMEOUT = 3 * 1000L;
坏味道19:不规范的变量命名
Iterate over the "entrySet" instead of the "keySet".
When only the keys from a map are needed in a loop, iterating the keySet makes sense. But when both the key and the value are needed, it's more efficient to iterate the entrySet, which will give access to both the key and value, instead.
for (String key : sArray.keySet()) {
String value = sArray.get(key);
if (value == null || value.equals("") || key.equalsIgnoreCase("sign")
|| key.equalsIgnoreCase("sign_type")) {
continue;
}
result.put(key, value);
}
for (Entry<String,String> entry : sArray.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
if (value == null || value.equals("") || key.equalsIgnoreCase("sign")
|| key.equalsIgnoreCase("sign_type")) {
continue;
}
result.put(key, value);
}
坏味道20:漏洞
Use a logger to log this exception.
try {
URL url = new URL(urlvalue);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
inputLine = in.readLine();
} catch (Exception e) {
e.printStackTrace();//漏洞
inputLine = "";
}
还有几个坏味道,我也不想修改了。
关注Yuema约吗公众号,回复”sq”,学习sonarqube代码质量检查工具使用与安装。
关注Yuema约吗公众号,回复”bankpay”,查看《支付宝网银直连SDK封装记上|强力去掉支付宝网银直连DEMO中56个坏味道 余下6个坏味道 Sonarqube无视阿里支付宝光环》,了解代码结构的艺术。
作者:钟代麒
出处:http://www.jishudao.com/
版权归作者所有,转载请注明出处