Java使用Spring Boot、Maven、Spring RestTemplate集成腾讯云通信 - Go语言中文社区

Java使用Spring Boot、Maven、Spring RestTemplate集成腾讯云通信


腾讯云通信介绍

云通信 - 文档首页 - 腾讯云文档平台 - 腾讯云

云通信(Instant Messaging)承载亿级 QQ 用户即时通信技术,数十年技术积累,腾讯云为您提供超乎寻常即时通信聊天服务。针对开发者的不同阶段需求及不同场景,云通信提供了一系列解决方案,包括: Android/iOS/Windows/Web 的 SDK 组件、服务端集成接口、第三方回调接口等,利用这些组件,可以在应用中构建自己的即时通信产品,解决开发者面临的高并发、高可用性的一系列问题。

服务端集成指引

服务端集成指引 - 云通信 - 文档首页 - 腾讯云文档平台 - 腾讯云

服务端集成 是 App 后台通过云通讯提供的一系列 REST API 来管理自身 App 的数据。云通信提供的 REST API 参见 REST API接口列表。

REST API 概览

REST API 概览 - 云通信 - 文档首页 - 腾讯云文档平台 - 腾讯云

REST API 是腾讯云提供给 App 后台的 HTTP 管理接口,其主要目的在于为 App 后台提供一个后台管理入口。目前云通信支持的 REST API 参见REST API 接口列表。
除了 REST API,App 控制台也可实现简单的数据管理、单发/群发消息,开发者可以在控制台上进行简单的数据管理、查看及测试。相比之下,REST API 接口较为原始,但管理能力却更为强大。
为了安全性,REST API 仅提供 HTTPS 接口。

用户名对应的签名usersig生成方法

使用Java原生接口生成签名的方法需要注意:

依赖jar包的引入(Maven方式):
├── bcpkix-jdk15on-152.jar
├── bcprov-jdk15on-152.jar
├── commons-codec-1.10.jar
├── gson-2.3.1.jar
├── json.jar
└── tls_signature.jar

其中前五个jar包的依赖声明可以通过maven仓库搜索找到:

 <dependency>
     <groupId>org.bouncycastle</groupId>
     <artifactId>bcpkix-jdk15on</artifactId>
     <version>1.52</version>
 </dependency>
 <dependency>
     <groupId>org.bouncycastle</groupId>
     <artifactId>bcprov-jdk15on</artifactId>
     <version>1.52</version>
 </dependency>
 <dependency>
     <groupId>commons-codec</groupId>
     <artifactId>commons-codec</artifactId>
     <version>1.10</version>
 </dependency>
 <dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.3.1</version>
</dependency>

tls_signature.jar由腾讯提供,可以通过官网提供的链接下载。下载后,可以将该jar包安装到本地maven仓库(mvn install:install-file -DgroupId=sun.microsystems.inc -DartifactId=rt -Dversion=1.6 -Dpackaging=jar -Dfile=rt.jar)或者安装到私有库后,在pom.xml文件中添加依赖即可:

<dependency>
    <groupId>com.tls.tls_sigature</groupId>
    <artifactId>tls_sigature</artifactId>
    <version>1.0</version>
</dependency>
调用SDK中的方法生成签名
public String generateSignature(String identifier) {
    tls_sigature.GenTLSSignatureResult result = null;
    try {
        result = GenTLSSignatureEx(tls.getSdkAppid(), identifier, tls.getPrivateKey());
        if (0 == result.urlSig.length()) {
            logger.error("GenTLSSignatureEx failed: " + result.errMessage + ",identifier:" + identifier);
            throw new Exception();
        }

        tls_sigature.CheckTLSSignatureResult checkResult = CheckTLSSignatureEx(result.urlSig, tls.getSdkAppid(), identifier, tls.getPublicKey());
        if (checkResult.verifyResult == false) {
            logger.error("CheckTLSSignature failed: " + result.errMessage + ",identifier:" + identifier);
            throw new Exception();
        }

    } catch (Exception e) {
        logger.error("GenTLSSignatureEx failed,identifier:" + identifier, e);
    }

    return result.urlSig;
}

使用Spring RestTemplate标准方式调用“REST API”的问题

之所以使用双引号来标注REST API,是因为他们提供的API并非标准的REST风格,笔者在调用时,因为过度相信他们所声称REST风格,代码写到怀疑人生。
独立模式账号导入接口 - 云通信 - 文档首页 - 腾讯云文档平台 - 腾讯云为例,使用POSTMAN调用接口,结果如图所示:
使用POSTMAN调用接口
返回结果Headers内容
可以看到,返回结果并非标准的JSON格式。所以,如果使用RestTemplate的标准方法去结束结果是获取不到对象的。
通过反复测试发现,使用标准的JSON格式传输POST请求,他们的“REST API”后端也是无法获取RequestBody中的数据。

使用Spring RestTemplate调用API的方法

/**
 * 构建Tim rest请求基本URL
 *
 * @param servicename 内部服务名,不同的servicename对应不同的服务类型。
 * @param command     命令字,与servicename组合用来标识具体的业务功能。
 * @return
 */
private String generateBaseUrl(String servicename, String command) {
    String url = "https://console.tim.qq.com/v4/" + servicename + "/" + command +
        "?sdkappid=" + tls.getSdkAppid() + "&identifier=" + tls.getAdministrator() +
        "&usersig=" + this.generateSignatureForAdministrator() + "&random=" + new Date().getTime() + "&contenttype=json";
    return url;
}

/**
 * 封装Tim的请求过程
 *
 * @param servicename 内部服务名,不同的servicename对应不同的服务类型。
 * @param command     命令字,与servicename组合用来标识具体的业务功能。
 * @param requestBody 请求体,JSON化
 * @return
 * @throws CheckedException
 */
private ResultBody sendRequstToTim(String servicename, String command, String requestBody) throws CheckedException {
    RestTemplate restTemplate = new RestTemplate();
    String baseUrl = this.generateBaseUrl(servicename, command);

    logger.debug("Tim请求:n" + "url:n" + baseUrl + ",nrequest:n" + requestBody);

    String bodyStr = restTemplate.postForObject(baseUrl, requestBody, String.class);
    ResultBody resultBody = new Gson().fromJson(bodyStr, ResultBody.class);

    if (resultBody.getActionStatus().equals("OK") && resultBody.getErrorCode().equals("0")) {
        return resultBody;
    } else {
        logger.error("Tim请求出错:" + "url:" + baseUrl + ",request:" + requestBody + "response:" + resultBody.toString());
        throw new Exception();
    }
}

postForObject方法声明:

@Nullable
public <T> T postForObject(java.lang.String url,
                                     @Nullable
                                     java.lang.Object request,
                                     java.lang.Class<T> responseType,
                                     java.lang.Object... uriVariables)
                              throws RestClientException

如上所示,使用postForObject方法调用API时,request不可以直接传入Java对象,必须将对象转换为Json字符串之后,作为String类型传入作为第二个参数。
返回结果类型声明responseType也必须设置为String.class。然后将返回的String转换为对象进行下一步的逻辑判断。

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/jiangshanwe/article/details/79999179
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-01 22:50:18
  • 阅读 ( 1612 )
  • 分类:职场

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢