任务描述:
项目使用阿里云物联网进行设备和后台服务平台通讯,考虑流量成本,参数多使用HEX类型传输,比字符串省一半字节数。以下分享一个通用的MessagePack解包方法,可以方便解析设备端传输的HEX类型的参数,和其它参数类型
分享一个messagePack的解析网址:https://toolslick.com/conversion/data/messagepack-to-json
废话不多说,直接上代码
Java解包
maven引入依赖包
<dependency>
<groupId>org.msgpack</groupId>
<artifactId>msgpack</artifactId>
<version>0.6.10</version>
</dependency>
<dependency>
<groupId>org.msgpack</groupId>
<artifactId>msgpack-core</artifactId>
<version>0.8.17</version>
</dependency>
实现方法
/**
* messagePack数据解包
* @param v
* @return
*/
public static Map<String,Object> unpackValue(byte[] data){
Map<String,Object> payload = null;
MessageUnpacker msg = MessagePack.newDefaultUnpacker(data);
try {
Value v = msg.unpackValue();
payload = (Map<String, Object>) getValue(v);
} catch (Exception e) {
logger.error("payload 解析出错 " , e);
}
return payload;
}
public static Object getValue(Value v) {
Object value = null;
switch (v.getValueType()) {
case NIL:
v.isNilValue(); // true
break;
case BOOLEAN:
boolean b = v.asBooleanValue().getBoolean();
value = b;
break;
case INTEGER:
IntegerValue iv = v.asIntegerValue();
if (iv.isInIntRange()) {
int i = iv.toInt();
value = i;
} else if (iv.isInLongRange()) {
long l = iv.toLong();
value = l;
} else {
BigInteger i = iv.toBigInteger();
value = i;
}
break;
case FLOAT:
FloatValue fv = v.asFloatValue();
float f = fv.toFloat(); // use as float
double d = fv.toDouble(); // use as double
value = d;
break;
case STRING:
String _s = v.asStringValue().asString();
value = _s;
break;
case BINARY:
byte[] mb = v.asBinaryValue().asByteArray();
value = HexUtils.byte2hexString(mb);
break;
case ARRAY:
ArrayValue a = v.asArrayValue();
value = a;
break;
case MAP:
Map<String,Object> map = new HashMap<>();
MapValue m = v.asMapValue();
for (Value _k : m.map().keySet()) {
String _ks = _k.asStringValue().asString();
map.put(_ks , getValue(m.map().get(_k)));
}
value = map;
break;
case EXTENSION:
ExtensionValue ev = v.asExtensionValue();
byte extType = ev.getType();
byte[] extValue = ev.getData();
break;
}
return value;
}
public static void main(String[] args) throws IOException {
String unpack = "87AB6D7367436D64436F646573A430313032A76D7367496E666F81AF72616E646F6D32506C7573456E6379C4084CDF4725C470F14CA88872FE07501AE607A648656164657283AA50726F647563744B6579AB61316C41506B32685A3834A74465764E616D65AE77696E646F77732D746573743031A9446576536563726574D92045324D5966447534414642486676544D6379687263744F4278374D68426E3573AB64657653657269616C4E6FB8383030333031303130303030303030314635423239393735AC6D736754696D655374616D70AA31353633343334323731AB6D7367456E637954797065A23030AA6D736756657273696F6EA23030";
byte[] array = HexUtils.hexString2byte(unpack);
Map<String,Object> pack = unpackValue(array);
System.out.println(pack);
}
总结
通过上面的方法,可以解析Map类型的MessagePack数据,无论设备端使用HEX字节数组类型,还是使用字符串或者其它数据类型,都可以解包成Map类型,方便后台后续处理,并且可以节省流量。