开发中数据对接涉及的常见事项

 0. 前言

       数据对接在开发过程中非常常见,与平台合作开发或者使用其他平台的接口是家常便饭,虽然对接的平台各有不同,但是对接方式基本大同小异,下面整理了一些自己在开发过程中对接时遇到的一些方式或事项。

        注:所列代码中较多使用Hutool工具类,需要在maven中导入,Hutool是一款非常便捷的工具包,感兴趣可以参看官方文档:Hutool — 🍬A set of tools that keep Java sweet.

<dependency>
     <groupId>cn.hutool</groupId>
     <artifactId>hutool-all</artifactId>
     <version>5.8.1</version>
     <scope>compile</scope>
</dependency>

1. 签名方式

1.1 参数排序拼接

       对请求参数按照字母顺序升序排列,一般采用 head + key1 + value1 + key2 + value2 + ... + tail 的模式,head一般为密钥等,tail常见密钥或者请求的json字符串,拼接后进行MD5加密,下面的代码为参数增无符号拼接,使用了Hutool的MD5加密工具,可以按需进行调整

// 非空参数名按字母排序,键值拼接,头/尾添加参数,MD5加密
public static String getMd5SignContent(Map<String, Object> sortedParams, String appCode, String body) {
    // 1. 根据key排序
    TreeMap<String, Object> map = new TreeMap<>(sortedParams);
    // 2. 拼接参数名和参数值
    StringBuilder content = new StringBuilder();
    map.forEach((key, value) -> {
        if (null != key && null != value) {
            content.append(key).append(value);
        }
    });
    String sign = appCode + content + body;
    // 3. 生成32位大写MD5值
    return DigestUtils.md5Hex(sign).toUpperCase();
}

1.2 某个字段加密

        直接对比如密钥等特殊字段进行加密,可以直接使用上面的最后一行代码

2. 请求方式

       借助Hutool的http工具进行访问,url为平台提供的接口地址,post为请求方式,可以换成get等,header中包含请求头信息,可以放置token/content-type等信息,body用于存放请求体信息,execute()执行返回请求结果

HttpResponse response = HttpRequest.post(url).header("Content-Type", CONTENT_TYPE).body(body).execute();

2.1 表单数据

private static final String CONTENT_TYPE = "application/x-www-form-urlencoded"

2.2 字节数据

private static final String CONTENT_TYPE = "application/octet-stream;charset=UTF-8";

2.3 JSON数据

private static final String CONTENT_TYPE = "application/json"

3. 数据传输方式

3.1 加密传输

       为了数据传输的安全性考虑,对传输数据进行加密处理,目前仅遇到过AES128加密,代码如下,使用了Hutool的加密对象

public class CryptoUtils {

    /**
     * 数据传输的加解密使用对称加解密算法 AES 128 位加解密,加解密模式采用 CBC,填充模式采用 PKCS5Padding 方式
     */
    private static final String MODE = "AES/CBC/PKCS5Padding";


    /**
     * AES128_CBC_PKCS5Padding 加密
     */
    public static String encodeByAes128(String data, String key, String vector) {
        SymmetricCrypto crypto = getSymmetricCrypto(key, vector);
        byte[] encrypt = crypto.encrypt(data.getBytes());
        return Base64.encode(encrypt);
    }


    /**
     * AES128_CBC_PKCS5Padding 解密
     */
    public static String decodeByAes128(String data, String key, String vector) {
        SymmetricCrypto crypto = getSymmetricCrypto(key, vector);
        // 先进行Base64解码
        byte[] decodedData = Base64.decode(data);
        byte[] decrypt = crypto.decrypt(decodedData);
        return new String(decrypt, UTF_8);
    }

    /**
     * 获取加解密对象
     */
    private static SymmetricCrypto getSymmetricCrypto(String key, String vector) {
        IvParameterSpec iv = new IvParameterSpec(vector.getBytes(UTF_8));
        SecretKeySpec spec = new SecretKeySpec(key.getBytes(UTF_8), "AES");
        return new SymmetricCrypto(MODE, spec, iv);
    }
}

3.2 压缩传输

        将数据进行压缩处理,以字节流形式传输,可以传输大量数据,下面的代码使用了Hutool的ZipUtil工具类,参数为json字符串

public class ZipUtils {

    /**
     * 压缩数据
     *
     * @param str 待压缩数据
     * @return 压缩后数据字节
     */
    public static byte[] zip(String str) {
        byte[] gz;
        try {
            // 压缩数据
            gz = ZipUtil.gzip(str.getBytes("UTF-8"));
        } catch (Exception e) {
            throw new BizException("数据压缩失败");
        }
        return Base64.encodeBase64(gz);
    }

    /**
     * 解压数据
     *
     * @param str 待解压数据
     * @return 解压后数据
     */
    public static String unzip(String str) {
        byte[] bt;
        try {
            // 解压数据
            bt = ZipUtil.unGzip(Base64.decodeBase64(str));
        } catch (Exception e) {
            throw new BizException("数据解压失败");
        }
        String sbody = null;
        try {
            sbody = new String(bt, "UTF-8");
        } catch (Exception e) {
            throw new BizException("不支持的编码格式");
        }
        return sbody;
    }
}

4. 其他事项

4.1 自增序列

       常用于签名参数中,用来判断同一请求或频繁请求,下面的代码是一秒内自增的4位自增序列,可以按需调整。

public class SeqUtils {
    private static final AtomicInteger counter = new AtomicInteger(0);
    private static volatile long lastUnixTime;

    /**
     * 4 位自增序列取自时间戳,同一秒内按序列自增长,新秒重计,如0001
     */
    public static synchronized String next(long unixTime){
        if (unixTime != lastUnixTime) {
            lastUnixTime = unixTime;
            counter.set(0);
        }
        return String.format("%04d", counter.incrementAndGet() % 9999);
    }
}

4.2 重定向

       常见于对接数据中包含图片的时候,当我们想去下载该图片发现图片大小为0,而直接点击链接却可以访问图片,是因为图片地址进行了重定向,可以通过访问原地址的返回状态码来判断,并获取重定向的地址。

private String getReDirectionUrl(String source) {
    // 请求目标地址
    HttpResponse response = HttpRequest.get(source).execute();
    // 获取相应状态码
    int status = response.getStatus();
    String location;
    // 302:重定向
    if (status == 302) {
        // 获取重定向地址
        location = response.header("Location");
        System.out.println("重定向地址" + location);
    } else {
        // 正常返回
        location = source;
    }
    return location;
}

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
广点通 API 对接文档是腾讯广点通广告平台提供给开发人员的一个重要参考文件,用于帮助开发人员对接广点通广告平台的相关接口和功能。文档提供了详细的接口说明、参数说明、返回值说明以及示例代码等内容,方便开发人员了解和使用广点通的功能和接口。 广点通 API 对接文档主要包括以下几个方面的内容: 1. 接口概述:介绍了广点通广告平台的基本信息、使用限制、申请和获取开发者账号的流程等内容。 2. 接口说明:列出了广点通广告平台支持的各类接口,并对每个接口进行了详细的解释,包括接口名称、调用方式、参数说明、返回值说明等。 3. 参数说明:对接涉及到的参数进行了详细的解释和说明,包括参数名称、数据类型、是否必填、取值范围等。 4. 返回值说明:对接口调用返回的结果进行了详细的解释和说明,包括返回值的数据结构、数据类型、各字段的含义等。 5. 示例代码:提供了一些常见的接口调用示例代码,方便开发人员直接参考和使用。 6. 常见问题:列出了一些开发人员在对接过程常见的问题和解决方案,帮助开发人员快速解决问题。 通过阅读广点通 API 对接文档,开发人员可以详细了解广点通广告平台的功能和接口,了解如何调用和使用接口,快速上手开发。同时,文档还提供了示例代码和常见问题解答,方便开发人员参考和解决问题。因此,广点通 API 对接文档是开发人员在对接广点通广告平台时不可或缺的重要参考资料。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值