Step By Step
一.创建"地理位置"物模型
二.设备接入并获取token
三.发送HTTP请求
一.创建"地理位置"物模型
添加地理位置物模型属性,权限为读写。
二.设备接入并获取token
- 在pom.xml文件中,添加以下依赖,引入阿里fastjson包
- 进行设备认证以获取设备token、使用获取的token进行持续地数据上报
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.68</version> </dependency>
package javasdk;/* * Copyright © 2019 Alibaba. All rights reserved. */ import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import javax.net.ssl.HttpsURLConnection; import com.alibaba.fastjson.JSONObject; /** * 设备使用HTTP协议接入阿里云物联网平台。 * 协议规范说明,请参见《HTTP协议规范》。 * 数据格式,请参见《HTTP连接通信》。 */ public class IotHttpClient { // 地域ID,以华东2(上海)为例。 private static String regionId = "cn-shanghai"; // 定义加密方式,MAC算法可选以下算法:HmacMD5、HmacSHA1,需和signmethod一致。 private static final String HMAC_ALGORITHM = "hmacsha1"; // token有效期7天,失效后需要重新获取。 private String token = null; /** * 初始化HTTP客户端。 * * @param productKey,产品key。 * @param deviceName,设备名称。 * @param deviceSecret,设备密钥。 */ public void conenct(String productKey, String deviceName, String deviceSecret) { try { // 注册地址。 URL url = new URL("https://iot-as-http." + regionId + ".aliyuncs.com/auth"); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-type", "application/json"); conn.setDoOutput(true); conn.setDoInput(true); // 获取URLConnection对象对应的输出流。 PrintWriter out = new PrintWriter(conn.getOutputStream()); // 发送请求参数。 out.print(authBody(productKey, deviceName, deviceSecret)); // flush输出流的缓冲。 out.flush(); // 获取URLConnection对象对应的输入流。 BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); // 读取URL的响应。 String result = ""; String line = ""; while ((line = in.readLine()) != null) { result += line; } System.out.println("----- auth result -----"); System.out.println(result); // 关闭输入输出流。 in.close(); out.close(); conn.disconnect(); // 获取token。 JSONObject json = JSONObject.parseObject(result); if (json.getIntValue("code") == 0) { token = json.getJSONObject("info").getString("token"); } } catch (Exception e) { e.printStackTrace(); } } private String authBody(String productKey, String deviceName, String deviceSecret) { // 构建认证请求。 JSONObject body = new JSONObject(); body.put("productKey", productKey); body.put("deviceName", deviceName); body.put("clientId", productKey + "." + deviceName); body.put("timestamp", String.valueOf(System.currentTimeMillis())); body.put("signmethod", HMAC_ALGORITHM); body.put("version", "default"); body.put("sign", sign(body, deviceSecret)); System.out.println("----- auth body -----"); System.out.println(body.toJSONString()); return body.toJSONString(); } /** * 设备端签名。 * * @param params,签名参数。 * @param deviceSecret,设备密钥。 * @return 签名十六进制字符串。 */ private String sign(JSONObject params, String deviceSecret) { // 请求参数按字典顺序排序。 Set<String> keys = getSortedKeys(params); // sign、signmethod和version除外。 keys.remove("sign"); keys.remove("signmethod"); keys.remove("version"); // 组装签名明文。 StringBuffer content = new StringBuffer(); for (String key : keys) { content.append(key); content.append(params.getString(key)); } // 计算签名。 String sign = encrypt(content.toString(), deviceSecret); System.out.println("sign content=" + content); System.out.println("sign result=" + sign); return sign; } /** * 获取JSON对象排序后的key集合。 * * @param json,需要排序的JSON对象。 * @return 排序后的key集合。 */ private Set<String> getSortedKeys(JSONObject json) { SortedMap<String, String> map = new TreeMap<String, String>(); for (String key : json.keySet()) { String vlaue = json.getString(key); map.put(key, vlaue); } return map.keySet(); } /** * 使用HMAC_ALGORITHM加密。 * * @param content,明文。 * @param secret,密钥。 * @return 密文。 */ private String encrypt(String content, String secret) { try { byte[] text = content.getBytes(StandardCharsets.UTF_8); byte[] key = secret.getBytes(StandardCharsets.UTF_8); SecretKeySpec secretKey = new SecretKeySpec(key, HMAC_ALGORITHM); Mac mac = Mac.getInstance(secretKey.getAlgorithm()); mac.init(secretKey); return byte2hex(mac.doFinal(text)); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 二进制转十六进制字符串。 * * @param b,二进制数组。 * @return 十六进制字符串。 */ private String byte2hex(byte[] b) { StringBuffer sb = new StringBuffer(); for (int n = 0; b != null && n < b.length; n++) { String stmp = Integer.toHexString(b[n] & 0XFF); if (stmp.length() == 1) { sb.append('0'); } sb.append(stmp); } return sb.toString().toUpperCase(); } public static void main(String[] args) { String productKey = ""; String deviceName = ""; String deviceSecret = ""; IotHttpClient client = new IotHttpClient(); client.conenct(productKey, deviceName, deviceSecret); } }
三.发送HTTP请求
本文以IPV4定位展示
Topic: /sys/"+productKey+"/"+deviceName+"/_thing/service/post
Payload: {"id":"123","version":"1.0","params":{"identifier":"Location.Position","serviceParams":{"type":"ip","ip":"10.1.1.1"}},"method":"_thing.service.post"}
/** * 发送消息。 * * @param topic,发送消息的Topic。 * @param payload,消息内容。 */ public void publish(String topic, byte[] payload) { try { // 注册地址。 URL url = new URL("https://iot-as-http." + regionId + ".aliyuncs.com/topic" + topic); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-type", "application/octet-stream"); conn.setRequestProperty("password", token); conn.setDoOutput(true); conn.setDoInput(true); // 获取URLConnection对象对应的输出流。 BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream()); out.write(payload); out.flush(); // 获取URLConnection对象对应的输入流。 BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); // 读取URL的响应。 String result = ""; String line = ""; while ((line = in.readLine()) != null) { result += line; } System.out.println("----- publish result -----"); System.out.println(result); // 关闭输入输出流。 in.close(); out.close(); conn.disconnect(); } catch (Exception e) { e.printStackTrace(); } }
参考文档