博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
系统对接API调用
阅读量:5124 次
发布时间:2019-06-13

本文共 8773 字,大约阅读时间需要 29 分钟。

在与公司外部系统对接时,API接口一般采用REST风格,对外暴露HTTP服务。只需要将入参封装好,并发起HTTP请求即可。具体请求流程如下图所示:

数据格式

 API调用参数分为系统参数和业务参数,请求时,系统参数是必传的,否则无法成功请求,业务参数由具体业务接口定义。

系统参数
名称 类型 必填 描述
apiKey String 分配给供应商的唯一身份标识
sign String 请求签名,生成规则参见签名机制
timestamp String 时间戳,参见时间戳 

API请求返回结果目前支持json和xml格式,具体返回格式由请求头中的Content-Type属性来决定。当Content-Type属性为application/xml时,返回xml格式,其余情况下统一返回json格式。返回结果包含以下字段

系统参数
名称 类型 必填 描述
returnCode int 结果码,具体值参见API返回码
errorMsg String 异常时错误信息
data String 返回结果
success boolean 是否请求成功

 

请求示例

我们以团期信息管理接口为例,假设我们需要维护团期,接口请求原始入参(业务参数+系统参数)如下.

{    "apiKey": "testApiKey",//系统参数    "timestamp": "2015-07-30 12:34:56",//系统参数    "agencyProductId": "test10001",//业务参数    "groupNum": "",//业务参数    "planInfo": [//业务参数        {            "planDateStr": "2015-07-18",            "datePriceList": [                {                    "schemeId": "scheme0001",                    "scheduleId": "schedule",                    "agencyBudget": 1000,                    "agencyBudgetChild": 500,                    "excludeChild": 1,                    "roomAddBudget": 100,                    "roomGapFlag": 1,                    "aheaddate": 4,                    "deadlinedate": 3,                    "deadlinehour": 18,                    "promoFlag": 1,                    "setGroupFlag": 1,                    "stuffEndDate": 5                }            ]        }    ]}

首先,我们需要根据现有参数生成签名,签名生成步骤如下:

1. 将入参按照一级key值进行排序(按字典顺序进行排序,忽略大小写),去掉value值为空的入参,我们将得到以下格式参数(业务参数+系统参数)如下

{    "agencyProductId": "test10001",    "apiKey": "testApiKey",    "planInfo": [        {            "planDateStr": "2015-07-18",            "datePriceList": [                {                    "schemeId": "scheme0001",                    "scheduleId": "schedule",                    "agencyBudget": 1000,                    "agencyBudgetChild": 500,                    "excludeChild": 1,                    "roomAddBudget": 100,                    "roomGapFlag": 1,                    "aheaddate": 4,                    "deadlinedate": 3,                    "deadlinehour": 18,                    "promoFlag": 1,                    "setGroupFlag": 1,                    "stuffEndDate": 5                }            ]        }    ],    "timestamp": "2015-07-30 12:34:56"}

2. 获取一级key和对应的value,例如上面参数中planInfo键,对应的值为[{"planDateStr":"2015-07-18","datePriceList":[{"schemeId":"scheme0001","scheduleId":"schedule","agencyBudget":1000,"agencyBudgetChild":500,"excludeChild":1,"roomAddBudget":100,"roomGapFlag":1,"aheaddate":4,"deadlinedate":3,"deadlinehour":18,"promoFlag":1,"setGroupFlag":1,"stuffEndDate":5}]}], 以字符串的形式把key+value拼接起来得到一个新的字符串(二级三级键不进行操作),如下:

planInfo[{"planDateStr":"2015-07-18","datePriceList":[{"schemeId":"scheme0001","scheduleId":"schedule","agencyBudget":1000, "agencyBudgetChild":500,"excludeChild":1,"roomAddBudget":100,"roomGapFlag":1,"aheaddate":4,"deadlinedate":3,"deadlinehour":18, "promoFlag":1,"setGroupFlag":1,"stuffEndDate":5}]}]

其他键值对同样如此,将拼装好的字符串再依次拼接起来,如下:

agencyProductIdtest10001apiKeytestApiKeyplanInfo[{"planDateStr":"2015-07-18","datePriceList":[{"schemeId":"scheme0001","scheduleId":"schedule", "agencyBudget":1000,"agencyBudgetChild":500,"excludeChild":1,"roomAddBudget":100,"roomGapFlag":1,"aheaddate":4,"deadlinedate":3,"deadlinehour":18, "promoFlag":1,"setGroupFlag":1,"stuffEndDate":5}]}]timestamp2015-07-30 12:34:56

3. 在拼好的字符串前后都加上签名密钥,我们假设密钥是ZbWjUMYevqT9Tnup4jRs,可以得到以下字符串:

ZbWjUMYevqT9Tnup4jRsagencyProductIdtest10001apiKeytestApiKeyplanInfo[{"planDateStr":"2015-07-18","datePriceList":[{"schemeId":"scheme0001", "scheduleId":"schedule","agencyBudget":1000,"agencyBudgetChild":500,"excludeChild":1,"roomAddBudget":100,"roomGapFlag":1,"aheaddate":4, "deadlinedate":3,"deadlinehour":18,"promoFlag":1,"setGroupFlag":1,"stuffEndDate":5}]}]timestamp2015-07-30 12:34:56ZbWjUMYevqT9Tnup4jRs

4. 对生成的字符串进行MD5加密,并将结果全部转为大写,获得签名值:

85F60EFE28BB4688F3BA4A37FF62C101

5. 将签名加入到入参中:

{    "agencyProductId": "test10001",    "apiKey": "testApiKey",    "planInfo": [        {            "planDateStr": "2015-07-18",            "datePriceList": [                {                    "schemeId": "scheme0001",                    "scheduleId": "schedule",                    "agencyBudget": 1000,                    "agencyBudgetChild": 500,                    "excludeChild": 1,                    "roomAddBudget": 100,                    "roomGapFlag": 1,                    "aheaddate": 4,                    "deadlinedate": 3,                    "deadlinehour": 18,                    "promoFlag": 1,                    "setGroupFlag": 1,                    "stuffEndDate": 5                }            ]        }    ],    "timestamp": "2015-07-30 12:34:56",    "sign": "85F60EFE28BB4688F3BA4A37FF62C101"}

6.发起HTTP请求。

附上MD5加密方法参考示例:

private static String Md5Encode(String str) throws NoSuchAlgorithmException {    StringBuilder sign = new StringBuilder();     MessageDigest md = MessageDigest.getInstance("MD5");    byte[] bytes = md.digest(str.getBytes());     for (int i = 0; i < bytes.length; i++) {        String hex = Integer.toHexString(bytes[i] & 0xFF);        if (hex.length() == 1) {            sign.append("0");        }        sign.append(hex.toUpperCase());    }    return sign.toString();}

在spring-core包中提供了一个MD5加密工具!

org.springframework.util.DigestUtils#md5DigestAsHex(byte[])

注意事项

1. 所有的请求和响应数据编码皆为utf-8格式

2. 生成签名时,空值的参数不参与校验

3. 生成签名时,参数名称和值大小写敏感

4. 排序规则为按字典顺序进行排序,忽略大小写

附代码实现:

public class APITest {    public static void main(String[] args) throws NoSuchAlgorithmException {        String s = "{\n" +                "    \"apiKey\": \"testApiKey\",\n" +                "    \"timestamp\": \"2015-07-30 12:34:56\",\n" +                "    \"agencyProductId\": \"test10001\",\n" +                "    \"groupNum\": \"\",\n" +                "    \"planInfo\": [\n" +                "        {\n" +                "            \"planDateStr\": \"2015-07-18\",\n" +                "            \"datePriceList\": [\n" +                "                {\n" +                "                    \"schemeId\": \"scheme0001\",\n" +                "                    \"scheduleId\": \"schedule\",\n" +                "                    \"agencyBudget\": 1000,\n" +                "                    \"agencyBudgetChild\": 500,\n" +                "                    \"excludeChild\": 1,\n" +                "                    \"roomAddBudget\": 100,\n" +                "                    \"roomGapFlag\": 1,\n" +                "                    \"aheaddate\": 4,\n" +                "                    \"deadlinedate\": 3,\n" +                "                    \"deadlinehour\": 18,\n" +                "                    \"promoFlag\": 1,\n" +                "                    \"setGroupFlag\": 1,\n" +                "                    \"stuffEndDate\": 5\n" +                "                }\n" +                "            ]\n" +                "        }\n" +                "    ]\n" +                "}";        String signature = getSignature(s, "ZbWjUMYevqT9Tnup4jRs");        System.out.println(Md5Encode(signature));    }    public static String getSignature(String requestData, String secretKey) {        //第一步,获取所有值非空的key        List
keyList = new ArrayList
(); Map
data = JsonUtil.toBean(requestData,Map.class); for (String key : data.keySet()) { if (key == null) { continue; } //value为null或空 if (data.get(key) == null || StringUtils.isBlank(data.get(key).toString())) { continue; } keyList.add(key); } //按名称排序并拼接成字符串 String[] arrayToSort = keyList.toArray(new String[keyList.size()]); Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER); StringBuilder sb = new StringBuilder(secretKey); for (String key : arrayToSort) { sb.append(key); sb.append(JsonUtil.toString(data.get(key))); } sb.append(secretKey); System.out.println(sb.toString()); return sb.toString(); } /** * MD5 加密 * @param str 需要加密的字符串 * @return 经过加密的字符串 * @throws NoSuchAlgorithmException */ private static String Md5Encode(String str) throws NoSuchAlgorithmException { StringBuilder sign = new StringBuilder(); MessageDigest md = MessageDigest.getInstance("MD5"); byte[] bytes = md.digest(str.getBytes()); for (int i = 0; i < bytes.length; i++) { String hex = Integer.toHexString(bytes[i] & 0xFF); if (hex.length() == 1) { sign.append("0"); } sign.append(hex.toUpperCase()); } return sign.toString(); }}

 

转载于:https://www.cnblogs.com/winner-0715/p/7348946.html

你可能感兴趣的文章
JDK安装与环境变量配置
查看>>
原生js实现缓动返回顶部
查看>>
1.4Activity保存现场状态
查看>>
关于mysql中GROUP_CONCAT函数的使用
查看>>
maven+springmvc下载excle文件——ie8可用
查看>>
OD使用教程20 - 调试篇20
查看>>
Java虚拟机(JVM)默认字符集详解
查看>>
给管道注册事件,用于用户是否登录!
查看>>
Java Servlet 过滤器与 springmvc 拦截器的区别?
查看>>
必须理解的分布式系统中雷同的集群技术及原理
查看>>
(tmp >> 8) & 0xff;
查看>>
linux命令之ifconfig详细解释
查看>>
NAT地址转换
查看>>
一个密码经过多次MD5加密能否提高安全性?Java MD5盐值加解密
查看>>
C#数组的合并拆分
查看>>
[转帖]什么是α射线、β射线、γ射线
查看>>
[转帖]Docker 清理占用的磁盘空间
查看>>
三羊献瑞(暴力破解)
查看>>
vmware创建虚拟机并安装centos7系统
查看>>
解决WCF接口无法传递object参数的问题
查看>>