OpenApi-Tool工具包除了依赖一个commons-logging.jar外,不依赖任何第三方jar,依赖commons-logging.jar包的原因主要是考虑到可以方便商户在使用的过程中实现commons-logging.jar包中的接口打印相应的日志。tool工具包是为企账通openapi接口订制的请求工具包,可以帮助商户快速接入企账通接口,工具包中提供了请求openapi需要用到的签名、验签、加密、解密、post请求和跳转地址拼装接口,cnvex-openapi-tool以jar形式提供,目前只提供了JAVA版本。
| 开发语言 | 资源下载 | 环境要求 |
|---|---|---|
| java版资源 | cnvex-openapi-tool | 适用于java语言、jdk1.7及以上开发环境 |
工具包提供了加密、解密、签名、验签、post请求和跳转请求地址拼装接口,其中post请求接口对签名和验签做了集成和跳转接口请求url拼装接口对签名做了集成,使用过程中只需要传入对应的公共参数和业务参数即可
cnvex-openapi-tool.jar—————————企账通openapi工具包编译文件jar
cnvex-openapi-tool-source.jar—————————企账通openapi工具包源码文件jar
commons-logging-1.1.1.jar——————企账通openapi工具包依赖的日志jar
commons-logging-1.1.1-sources.jar———企账通工具包依赖的日志源码jar
集成企账通接口需要引入的文件是:
cnvex-openapi-tool.jar
commons-logging-1.1.1.jar
若进一步了解代码实现请引入文件:
cnvex-openapi-tool-source.jar
commons-logging-1.1.1-sources.jar
接入工具提供给商户的接口通过QztClient.getService().####的方式调用,提供如下接口
/**
* ASE加密
*
* @param plainText 明文
* @param secretKey 商户安全码
* @return 密文
*/
String AESEncrypt(String plainText, String secretKey);
/**
* 获取签名结果(MD5方式)
* @param object 需要签名的数据
* @param secretyKey 商户私钥
* @return
*/
String sign(Object object, String secretyKey);
/**
* 获取签名结果(MD5方式)
* @param parameters 需要签名的数据
* @param secretyKey 商户私钥
* @return
*/
String sign(List<String> parameters, String secretyKey);
/**
* 获取签名结果(MD5方式)
* @param waitSignStr 需要签名的数据
* @param secretyKey 商户私钥
* @return
*/
String sign(String waitSignStr, String secretyKey);
/**
* 获取签名结果(MD5方式)
* @param formData 需要签名的数据
* @param securityCheckKey 商户私钥
* @return
*/
String sign(Map<String, String> formData, String securityCheckKey);
/**
* 同步请求(默认链接主机和从主机读取数据超时为60秒)
* @param url 请求服务地址
* @param params 请求参数
* @param securityKey 商户密钥
* @return
*/
String doPost(String url, Map<String, String> params, String securityKey);
/**
* 同步请求
* @param url 请求服务地址
* @param params 请求参数
* @param securityKey 商户密钥
* @param connectTimeout 连接主机的超时时间(单位:秒)
* @param readTimeout 从主机读取数据超时(单位:秒)
* @return
*/
String doPost(String url, Map<String, String> params, String securityKey, int connectTimeout, int readTimeout);
/**
* 跳转url拼装
* @param requestData
* @return
*/
String redirect(String url, Map<String, String> requestData, String securityCheckKey);
/**
* 验证签名(MD5方式)
* @param responseStr 服务返回json报文串
* @param securityCheckKey 商户私钥
* @return
*/
boolean verificationSign(String responseStr, String securityCheckKey);
/**
* 验证签名(MD5方式)
* @param dataMap 针对通知报文(异步、跳转),接收数据转化为map,传入进行验签
* @param securityCheckKey 商户私钥
* @return
*/
boolean verificationSign(Map<String, String> dataMap, String securityCheckKey)
/**
* ASE解密
*
* @param plainText 密文
* @param secretKey 商户安全码
* @return 明文
*/
String AESDecrypt(String plainText, String secretKey);
public class TestsynService {
private static String partnerId = "2018*************750";
private static String key = "55013b3352*************b24ed4303";
private static String url = "http://open.qizhangtong.com:8810/gateway.html";
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put(FieldsConstants.REQUEST_NO, Ids.oid());
map.put(FieldsConstants.PARTNER_ID, partnerId);
map.put("service", "bankNoQuery");
map.put("version", "1.0");
map.put("signType";, "MD5");
map.put("protocol";, "HTTP_FORM_JSON");
map.put("bankId", "CCB");
map.put("districtName", "宁波市");
// 同步请求
try {
//请求响应,请求地址可根据QztConstants.GATEWAY取到配置文件中配置的请求地址
String responseStr = QztClient.getService().doPost(QztConstants.GATEWAY, map, key);
System.out.println("响应报文:" + responseStr);
//验签
boolean isPass = QztClient.getService().verificationSign(responseStr, key);
if(isPass) {
//TODO验签通过,进行业务逻辑处理
JSONObject responseObject = JSON.parseObject(responseStr);
if(StringUtils.equals(responseObject.get("resultCode"), ApiServiceResultCode.SUCCESS.getCode())) {
//TODO:处理成功,进行业务逻辑出路
、、、、
}else {
//TODO:处理失败进行业务逻辑处理
、、、、
}
}else {
//TODO:验签不过,进行业务逻辑处理
}
} catch (Exception e) {
//TODO:异常处理
}
}
}
public class TestSynServiceRedirect {
private static String partnerId = "2018*************750";
private static String key = "55013b3352*************b24ed4303";
private static String url = "http://open.qizhangtong.com:8810/gateway.html";
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put(FieldsConstants.PARTNER_ID, partnerId);
map.put(FieldsConstants.REQUEST_NO, Ids.oid());
map.put("service", "mpayResetLoginPasswordRedirect");
map.put("outOrderNo", "outNo20160526173456");
map.put("userId", "20160*************90322");
map.put(FieldsConstants.RETURN_URL,
"http://*************:8080/returnView.html");
map.put(FieldsConstants.NOTIFY_URL,
"http://*************:8080/testNotify.html");
// 跳转请求
try {
//集成了签名
String redirectUrl = QztClient.getService().redirect(url, map, key);
System.out.println("跳转地址:" + redirectUrl);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class TestSign {
private static String key = "55013b3352*************b24ed4303";
public static void main(String[] args) {
//字符串请求签名
String waitSignStr = "age=28&name=wck";
String strSign = QztClient.getService().sign(waitSignStr, key);
System.out.println("字符串签名:"+strSign);
//list请求签名
List<String> listStr = new ArrayList<String>();
listStr.add("age=28");
listStr.add("name=wck");
String listSign = QztClient.getService().sign(listStr, key);
System.out.println("list签名:"+listSign);
//map请求签名
Map<String,String> mapStr = new HashMap<String,String>();
mapStr.put("age", "28");
mapStr.put("name", "wck");
String mapSign = QztClient.getService().sign(mapStr, key);
System.out.println("map签名:"+mapSign);
//对象请求签名
User user = new User();
user.setName("wck");
user.setAge("28");
String objectSign = QztClient.getService().sign(user, key);
System.out.println("对象签名:"+objectSign);
}
}
public class TestVerificationSign {
private static String key = "55013b3352*************b24ed4303";
public static void main(String[] args) {
String waitSignStr = "age=28&name=wck&signType=MD5";
String strSign = QztClient.getService().sign(waitSignStr, key);
String responseStr = "{\"signType\":\"MD5\",\"age\":\"28\",\"name\":\"wck\",\"sign\":\""+strSign+"\"}";
boolean isPass = QztClient.getService().verificationSign(responseStr, key);
System.out.println("验签结果:"+isPass);
}
}
注:商户端在收集请求参数,通知参数时,需要获取请求域(scope)内所有的参数。
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
/**
* 异步通知请求参数转map
* @return
*/
public static Map<String, String> getNotifyParameters(ServletRequest request) {
Map<String, String> params = new TreeMap<>();
Enumeration<String> enumeration = request.getParameterNames();
while (enumeration.hasMoreElements()) {
String name = enumeration.nextElement();
String[] values = request.getParameterValues(name);
if (values == null || values.length == 0) {
continue;
}
String value = values[0];
// 注意:这里是判断不为null,没有包括空字符串的判断。
if (value != null) {
params.put(name, value);
}
}
return params;
}
/**
* 同步跳转通知请求参数转map
* @return
*/
public static Map<String, String> getRedirectParameters(ServletRequest request) {
Map<String, String> params = new TreeMap<>();
Enumeration<String> enumeration = request.getParameterNames();
while (enumeration.hasMoreElements()) {
String name = enumeration.nextElement();
String[] values = request.getParameterValues(name);
if (values == null || values.length == 0) {
continue;
}
String value = convert(values[0]);
// 注意:这里是判断不为null,没有包括空字符串的判断。
if (value != null) {
params.put(name, value);
}
}
return params;
}
/**
* 将字符编码
* @return
*/
public static String convert(String target) {
try {
return new String(target.trim().getBytes("ISO-8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e) {
return target;
}
}
/**
* 同步跳转通知报文验签示例
* @return
*/
@RequestMapping("/returnView")
public ModelAndView returnView(HttpServletRequest getRequest, Model model) {
Map<String, String> responseMap = getRedirectParameters(getRequest);
boolean signResult = QztClient.getService().verificationSign(responseMap,
QztConstants.SECRETKEY);
if (signResult) {
System.out.println("跳转报文验签成功!!!!");
} else {
System.out.println("跳转报文验签失败!!!!");
}
ModelAndView view = new ModelAndView("blank.jsp", responseMap);
return view;
}
/**
* 异步通知报文验签示例
* @return
*/
@RequestMapping("/testNotify")
public void testNotify(HttpServletRequest getRequest, HttpServletResponse response) {
Map<String, String> notifyData = getNotifyParameters(getRequest);
boolean signResult = QztClient.getService().verificationSign(notifyData,key);
if (signResult) {
System.out.println("异步通知验签成功!!!!");
Servlets.writeResponse(response, "success",null);
} else {
System.out.println("异步通知验签失败!!!!");
Servlets.writeResponse(response, "failure",null);
}
}
public class TestEncryptDecrypt {
private static String key = "55013b3352*************b24ed4303";
public static void main(String[] args) {
String enStr = QztClient.getService().AESEncrypt("23424234", key);
String deStr = QztClient.getService().AESDecrypt(enStr, key);
System.out.println("加密结果:"+enStr);
System.out.println("解密结果:"+deStr);
}
}
Dates————-时间工具类
DigestUtil——签名工具类
Encodes———-编码解码工具类
Ids—————-orderNo生成器
Reflections—-反射工具类
StringUtils—-字符串操作工具类
WebUtils———请求工具类
工具中集成了fastjson等等,使用的过程中可以参考cnvex-openapi-tool-source.jar包查看