前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >物联网控制台数据同步--客户端java脚本(Spring Boot)

物联网控制台数据同步--客户端java脚本(Spring Boot)

原创
作者头像
loganydxie
发布2021-12-31 14:50:21
7202
发布2021-12-31 14:50:21
举报
文章被收录于专栏:物联网平台体验

用户的个性化业务需求需要将产品下所有设备上报的数据传输至用户自有的服务器上进行处理,平台提供了 HTTP 转发服务,将设备上报数据实时 POST 到用户的 HTTP 服务器的能力。

客户需要一个HTTP的服务器去接收控制台传过来的设备信息。http服务器需要具备的功能如下:

  • 通过token验证签名
  • 增加第三方http服务确认 请求来自物联网平台,编写在 body 中原样返回 Echostr 参数内容的示例
  • 接收控制台同步的设备信息

操作步骤

  1. 登录 物联网开发平台 ,选择【公共实例】或您购买的【标准企业实例】。
  2. 进入项目列表页面,单击【项目 ID】进入项目详情页。
  3. 单击左侧菜单【数据流转】- 【规则引擎】 进入“规则引擎”页面,单机【新建规则】创建规则,编辑“筛选数据”和“行为操作。具体操作流程参考规则引擎文档 - 数据转发到第三方服务
  4. URL 保存成功后,跳转到列表页,可开启该产品的【生效状态】,完成该产品的数据同步配置。
  5. 如需配置项目中的多个产品,需要逐一对产品进行配置。

客户端java脚本demo(Spring Boot)

如下示例代码是创建的Spring Boot项目,所有的业务逻辑均已在controller中展示

代码语言:javascript
复制
package com.example.datatrans.controller;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.stream.Collectors;

@RestController
public class DataTransCron {
    static final String FILE_NAME = "device_report.txt";

    @RequestMapping("deal_data")
    public void dealDate(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //私有token,必须与页面写的token一致
        String token = "此处填写【增加鉴权token】时,页面中填写的token";
        List<String> list = new ArrayList<>();
        String signature = "";
        String echostr = "";

        list.add(token);
        if (request.getMethod().equalsIgnoreCase("GET")) {
            //解析 header
            Enumeration headerNames = request.getHeaderNames();
            while (headerNames.hasMoreElements()) {
                String key = (String) headerNames.nextElement();
                String value = request.getHeader(key);
                System.out.printf("%s=%s\n",key,value);
                if (key.equalsIgnoreCase("Echostr")){
                    echostr = value;
                }
                if (key.equalsIgnoreCase("Signature")){
                    signature = value;
                }
                if (key.equalsIgnoreCase("Timestamp")){
                    list.add(value);
                }
                if (key.equalsIgnoreCase("Nonce")){
                    list.add(value);
                }
            }

            //校验签名
            boolean success = checkSign(list, signature);

            // 返回json字符串给客户端
            response.setStatus(HttpStatus.OK.value());
            response.setHeader("Content-Type", "application/json; charset=utf-8");
            response.setCharacterEncoding("UTF-8");
            response.getWriter().print(success ? echostr : "验签失败");
            //response.getWriter().print(echostr);
        } else if (request.getMethod().equalsIgnoreCase("POST")) {
            // 调用json包的解析,解析请求body
            String body = getBodyFromReq(request);
            System.out.println("request json : " + body);
            //将body写入文件
            writeInFile(FILE_NAME,body);
        } else {
            response.setStatus(HttpStatus.NOT_FOUND.value());
        }

    }

    /**
     * 校验签名
     * @param list
     * @param signature
     * @return
     */
    private boolean checkSign(List<String> list, String signature) {

        //防止传入空的字符串骗过校验
        if (list.size() == 0 || signature.length() == 0) {
            return false;
        }

        String tmpStr = list.stream()
                .sorted((a, b) -> a.compareTo(b))
                .map(String::valueOf)
                .collect(Collectors.joining(""));
        System.out.println("tmpStr = " + tmpStr);

        //加密生成hexValue
        MessageDigest sha = null;
        try {
            sha = MessageDigest.getInstance("SHA");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        byte[] md5Bytes = sha.digest(tmpStr.getBytes(StandardCharsets.UTF_8));
        //System.out.println("md5Bytes = " + md5Bytes);

        StringBuffer hexValue = new StringBuffer();
        for (int i = 0; i < md5Bytes.length; i++) {
            int val = ((int) md5Bytes[i]) & 0xff;
            if (val < 16) {
                hexValue.append("0");
            }
            hexValue.append(Integer.toHexString(val));
        }
        //System.out.println("hexValue = " + hexValue);
        //System.out.println("是否相等 : " + hexValue.toString().equalsIgnoreCase(signature));
        
        return hexValue.toString().equals(signature);
    }

    /**
     * 从请求req中获取body对象
     * @param request
     * @return
     */
    private String getBodyFromReq(HttpServletRequest request)
    {

        BufferedReader br = null;
        StringBuilder sb = new StringBuilder("");
        try
        {
            br = request.getReader();
            String str;
            while ((str = br.readLine()) != null)
            {
                sb.append(str);
            }
            br.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if (null != br)
            {
                try
                {
                    br.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }

    /**
     * 将content内容写到fileName文件中。如果文件不存在,创建文件,否则文件尾插入content
     * @param fileName
     * @param content
     */
    private void writeInFile(String fileName, String content) {
        BufferedWriter out = null;
        try {
            out = new BufferedWriter(new OutputStreamWriter(
                    new FileOutputStream(fileName, true)));
            out.write(content+"\r\n");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

用户收到的token验证的get请求示例如下:

代码语言:javascript
复制
GET / HTTP/1.1
Host: **.**.**.**:4443
User-Agent: Go-http-client/1.1
Content-Type: application/json
Echostr: UPWIAFASvDUFcTEE
Nonce: testrance
Signature: abb6c316a8134596d825c5a1295bfa6f7657664d
Timestamp: 1623149590
Accept-Encoding: gzip

用户收到返回的验证参数是:

代码语言:javascript
复制
HTTP/1.1 200 OK
Date: Tue, 08 Jun 2021 10:53:10 GMT
Content-Length: 16
Content-Type: text/plain; charset=utf-8

UPWIAFASvDUFcTEE

用户收到控制台同步的信息示例如下:

代码语言:javascript
复制
{
"payload": {
    "clientToken": "DEP****YAS4-38",
    "method": "report",
    "params": {
        "brightness": 58,
        "color": 2,
        "name": "dev001",
        "power_switch": 1
    }
},
"seq": 1000000000,
"timestamp": 1579055948,
"topic": "$thing/up/property/DEP****YAS4/dev001",
"devicename": "dev001",
"productid": "DEP****YAS4"
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 操作步骤
  • 客户端java脚本demo(Spring Boot)
相关产品与服务
云服务器
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档