|
|
|
|
@ -20,9 +20,11 @@ import java.sql.ResultSet;
|
|
|
|
|
import java.sql.SQLException;
|
|
|
|
|
import java.sql.Timestamp;
|
|
|
|
|
import java.text.SimpleDateFormat;
|
|
|
|
|
import java.time.LocalDate;
|
|
|
|
|
import java.time.LocalDateTime;
|
|
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
@Service
|
|
|
|
|
@Slf4j
|
|
|
|
|
@ -30,12 +32,13 @@ public class TDengineService {
|
|
|
|
|
@Resource
|
|
|
|
|
private JdbcTemplate jdbcTemplate;
|
|
|
|
|
|
|
|
|
|
@DS("tdengine")
|
|
|
|
|
public void testConnection() {
|
|
|
|
|
String testSQL = "SELECT SERVER_STATUS()";
|
|
|
|
|
jdbcTemplate.queryForObject(testSQL, Integer.class);
|
|
|
|
|
System.out.println("TDengine连接正常");
|
|
|
|
|
}
|
|
|
|
|
// @DS("tdengine")
|
|
|
|
|
// public void testConnection() {
|
|
|
|
|
// String testSQL = "SELECT SERVER_STATUS()";
|
|
|
|
|
// jdbcTemplate.queryForObject(testSQL, Integer.class);
|
|
|
|
|
// log.info("TDengine连接正常");
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
@DS("tdengine")
|
|
|
|
|
public void initDatabaseAndTable(Long id) {
|
|
|
|
|
@ -61,10 +64,9 @@ public class TDengineService {
|
|
|
|
|
tableName, id);
|
|
|
|
|
jdbcTemplate.execute(createTableSql);
|
|
|
|
|
|
|
|
|
|
System.out.println("TDengine表创建成功: " + tableName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
log.info("TDengine表创建成功 {}", tableName);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@ -93,41 +95,9 @@ public class TDengineService {
|
|
|
|
|
String timestampStr = sdf.format(ts);
|
|
|
|
|
result.put("timestamp", timestampStr);
|
|
|
|
|
|
|
|
|
|
// 读取 query_data(二进制字段)
|
|
|
|
|
byte[] blob = rs.getBytes("query_data");
|
|
|
|
|
if (blob != null) {
|
|
|
|
|
String jsonStr = new String(blob, StandardCharsets.UTF_8);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 1. 先去除外层的双引号(如果存在)
|
|
|
|
|
String trimmed = jsonStr.trim();
|
|
|
|
|
if (trimmed.startsWith("\"") && trimmed.endsWith("\"")) {
|
|
|
|
|
trimmed = trimmed.substring(1, trimmed.length() - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2. 检查是否是十六进制字符串
|
|
|
|
|
if (isHexString(trimmed)) {
|
|
|
|
|
// 3. 十六进制解码
|
|
|
|
|
String decodedJson = hexToString(trimmed);
|
|
|
|
|
result.put("queryData", decodedJson);
|
|
|
|
|
} else {
|
|
|
|
|
// 如果不是十六进制,尝试直接解析
|
|
|
|
|
ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
|
List<Map<String, Object>> queryData = objectMapper.readValue(
|
|
|
|
|
trimmed,
|
|
|
|
|
new TypeReference<List<Map<String, Object>>>() {}
|
|
|
|
|
);
|
|
|
|
|
result.put("queryData", queryData);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
System.err.println("解析JSON失败: " + e.getMessage());
|
|
|
|
|
result.put("queryData", new ArrayList<>());
|
|
|
|
|
result.put("rawData", jsonStr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
result.put("queryData", new ArrayList<>());
|
|
|
|
|
}
|
|
|
|
|
result.put("queryData", decodeQueryData(blob));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
result.put("deviceId", id);
|
|
|
|
|
@ -136,8 +106,7 @@ public class TDengineService {
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
System.out.println("查询设备" + id + "的最新数据时发生异常: " + e.getMessage());
|
|
|
|
|
// 可以考虑记录更详细的日志,或抛出更明确的业务异常
|
|
|
|
|
log.error("查询设备id为 {} 的最新数据时发生异常", id, e);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -177,7 +146,7 @@ public class TDengineService {
|
|
|
|
|
ps.setBytes(2, blobData);
|
|
|
|
|
}) > 0;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
System.out.println("向设备" + id + "插入数据时发生异常: " + e.getMessage());
|
|
|
|
|
log.error("向设备id为 {} 插入数据时发生异常", id, e);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -200,42 +169,9 @@ public class TDengineService {
|
|
|
|
|
result.put("timestamp", rs.getTimestamp("ts"));
|
|
|
|
|
result.put("deviceId", id);
|
|
|
|
|
|
|
|
|
|
// 读取 query_data(二进制字段)
|
|
|
|
|
byte[] blob = rs.getBytes("query_data");
|
|
|
|
|
if (blob != null) {
|
|
|
|
|
String jsonStr = new String(blob, StandardCharsets.UTF_8);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 1. 先去除外层的双引号(如果存在)
|
|
|
|
|
String trimmed = jsonStr.trim();
|
|
|
|
|
if (trimmed.startsWith("\"") && trimmed.endsWith("\"")) {
|
|
|
|
|
trimmed = trimmed.substring(1, trimmed.length() - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2. 检查是否是十六进制字符串
|
|
|
|
|
if (isHexString(trimmed)) {
|
|
|
|
|
// 3. 十六进制解码
|
|
|
|
|
String decodedJson = hexToString(trimmed);
|
|
|
|
|
|
|
|
|
|
result.put("queryData", decodedJson);
|
|
|
|
|
} else {
|
|
|
|
|
// 如果不是十六进制,尝试直接解析
|
|
|
|
|
ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
|
List<Map<String, Object>> queryData = objectMapper.readValue(
|
|
|
|
|
trimmed,
|
|
|
|
|
new TypeReference<List<Map<String, Object>>>() {}
|
|
|
|
|
);
|
|
|
|
|
result.put("queryData", queryData);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
System.err.println("解析JSON失败: " + e.getMessage());
|
|
|
|
|
result.put("queryData", new ArrayList<>());
|
|
|
|
|
result.put("rawData", jsonStr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
result.put("queryData", new ArrayList<>());
|
|
|
|
|
}
|
|
|
|
|
result.put("queryData", decodeQueryData(blob));
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
@ -243,8 +179,7 @@ public class TDengineService {
|
|
|
|
|
} catch (EmptyResultDataAccessException e) {
|
|
|
|
|
return Collections.singletonList(createEmptyResult(id));
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
System.err.println("查询设备" + id + "的最新数据时发生异常: " + e.getMessage());
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
log.error("查询设备id为 {} 的最新数据时发生异常", id, e);
|
|
|
|
|
return Collections.singletonList(createEmptyResult(id));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -267,37 +202,11 @@ public class TDengineService {
|
|
|
|
|
byte[] bytes = Hex.decodeHex(hex);
|
|
|
|
|
return new String(bytes, StandardCharsets.UTF_8);
|
|
|
|
|
} catch (DecoderException e) {
|
|
|
|
|
throw new RuntimeException("十六进制解码失败: " + e.getMessage(), e);
|
|
|
|
|
log.error("十六进制解码失败: {}", e);
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private List<Map<String, Object>> parseJsonData(byte[] blob) {
|
|
|
|
|
if (blob == null || blob.length == 0) {
|
|
|
|
|
return new ArrayList<>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
String jsonStr = new String(blob, StandardCharsets.UTF_8);
|
|
|
|
|
|
|
|
|
|
// 检查是否是有效的JSON
|
|
|
|
|
if (jsonStr.trim().startsWith("[") && jsonStr.trim().endsWith("]")) {
|
|
|
|
|
ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
|
return objectMapper.readValue(jsonStr,
|
|
|
|
|
new TypeReference<List<Map<String, Object>>>() {});
|
|
|
|
|
} else {
|
|
|
|
|
// 可能是字符串化的JSON,尝试去除引号
|
|
|
|
|
jsonStr = jsonStr.trim();
|
|
|
|
|
if (jsonStr.startsWith("\"") && jsonStr.endsWith("\"")) {
|
|
|
|
|
jsonStr = jsonStr.substring(1, jsonStr.length() - 1);
|
|
|
|
|
return new ObjectMapper().readValue(jsonStr,
|
|
|
|
|
new TypeReference<List<Map<String, Object>>>() {});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
System.err.println("解析JSON数据失败: " + e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new ArrayList<>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Map<String, Object> createEmptyResult(Long deviceId) {
|
|
|
|
|
Map<String, Object> result = new HashMap<>();
|
|
|
|
|
@ -343,42 +252,9 @@ public class TDengineService {
|
|
|
|
|
result.put("timestamp", rs.getTimestamp("ts"));
|
|
|
|
|
result.put("deviceId", id);
|
|
|
|
|
|
|
|
|
|
// 读取 query_data(二进制字段)
|
|
|
|
|
byte[] blob = rs.getBytes("query_data");
|
|
|
|
|
if (blob != null) {
|
|
|
|
|
String jsonStr = new String(blob, StandardCharsets.UTF_8);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 1. 先去除外层的双引号(如果存在)
|
|
|
|
|
String trimmed = jsonStr.trim();
|
|
|
|
|
if (trimmed.startsWith("\"") && trimmed.endsWith("\"")) {
|
|
|
|
|
trimmed = trimmed.substring(1, trimmed.length() - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2. 检查是否是十六进制字符串
|
|
|
|
|
if (isHexString(trimmed)) {
|
|
|
|
|
// 3. 十六进制解码
|
|
|
|
|
String decodedJson = hexToString(trimmed);
|
|
|
|
|
|
|
|
|
|
result.put("queryData", decodedJson);
|
|
|
|
|
} else {
|
|
|
|
|
// 如果不是十六进制,尝试直接解析
|
|
|
|
|
ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
|
List<Map<String, Object>> queryData = objectMapper.readValue(
|
|
|
|
|
trimmed,
|
|
|
|
|
new TypeReference<List<Map<String, Object>>>() {}
|
|
|
|
|
);
|
|
|
|
|
result.put("queryData", queryData);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
System.err.println("解析JSON失败: " + e.getMessage());
|
|
|
|
|
result.put("queryData", new ArrayList<>());
|
|
|
|
|
result.put("rawData", jsonStr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
result.put("queryData", new ArrayList<>());
|
|
|
|
|
}
|
|
|
|
|
result.put("queryData", decodeQueryData(blob));
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
@ -451,31 +327,12 @@ public class TDengineService {
|
|
|
|
|
|
|
|
|
|
// 读取 query_data(二进制字段)
|
|
|
|
|
byte[] blob = rs.getBytes("query_data");
|
|
|
|
|
if (blob != null) {
|
|
|
|
|
// 转为字符串
|
|
|
|
|
String json = new String(blob, StandardCharsets.UTF_8).trim();
|
|
|
|
|
|
|
|
|
|
// 去除 TDengine 中可能存在的外层双引号
|
|
|
|
|
if (json.startsWith("\"") && json.endsWith("\"")) {
|
|
|
|
|
json = json.substring(1, json.length() - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果是十六进制字符串,先解码
|
|
|
|
|
if (isHexString(json)) {
|
|
|
|
|
json = hexToString(json);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 统一约定:queryData 始终返回 String,由上层决定是否解析 JSON
|
|
|
|
|
result.put("queryData", json);
|
|
|
|
|
} else {
|
|
|
|
|
// 没有数据时返回空数组字符串
|
|
|
|
|
result.put("queryData", "[]");
|
|
|
|
|
}
|
|
|
|
|
result.put("queryData", decodeQueryData(blob));
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
});
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("TDengine 查询失败,deviceId={} ,td表不存在", deviceId);
|
|
|
|
|
log.error("TDengine 查询失败,deviceId={} ,td表不存在", deviceId,e);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -557,26 +414,7 @@ public class TDengineService {
|
|
|
|
|
|
|
|
|
|
// 读取 query_data(二进制字段)
|
|
|
|
|
byte[] blob = rs.getBytes("query_data");
|
|
|
|
|
if (blob != null) {
|
|
|
|
|
// 转为字符串
|
|
|
|
|
String json = new String(blob, StandardCharsets.UTF_8).trim();
|
|
|
|
|
|
|
|
|
|
// 去除 TDengine 中可能存在的外层双引号
|
|
|
|
|
if (json.startsWith("\"") && json.endsWith("\"")) {
|
|
|
|
|
json = json.substring(1, json.length() - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果是十六进制字符串,先解码
|
|
|
|
|
if (isHexString(json)) {
|
|
|
|
|
json = hexToString(json);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 统一约定:queryData 始终返回 String,由上层决定是否解析 JSON
|
|
|
|
|
map.put("queryData", json);
|
|
|
|
|
} else {
|
|
|
|
|
// 没有数据时返回空数组字符串
|
|
|
|
|
map.put("queryData", "[]");
|
|
|
|
|
}
|
|
|
|
|
map.put("queryData", decodeQueryData(blob));
|
|
|
|
|
|
|
|
|
|
return map;
|
|
|
|
|
});
|
|
|
|
|
@ -607,29 +445,10 @@ public class TDengineService {
|
|
|
|
|
map.put("timestamp", rs.getTimestamp("ts"));
|
|
|
|
|
map.put("deviceId", deviceId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 读取 query_data(二进制字段)
|
|
|
|
|
byte[] blob = rs.getBytes("query_data");
|
|
|
|
|
if (blob != null) {
|
|
|
|
|
// 转为字符串
|
|
|
|
|
String json = new String(blob, StandardCharsets.UTF_8).trim();
|
|
|
|
|
map.put("queryData", decodeQueryData(blob));
|
|
|
|
|
|
|
|
|
|
// 去除 TDengine 中可能存在的外层双引号
|
|
|
|
|
if (json.startsWith("\"") && json.endsWith("\"")) {
|
|
|
|
|
json = json.substring(1, json.length() - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果是十六进制字符串,先解码
|
|
|
|
|
if (isHexString(json)) {
|
|
|
|
|
json = hexToString(json);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 统一约定:queryData 始终返回 String,由上层决定是否解析 JSON
|
|
|
|
|
map.put("queryData", json);
|
|
|
|
|
} else {
|
|
|
|
|
// 没有数据时返回空数组字符串
|
|
|
|
|
map.put("queryData", "[]");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return map;
|
|
|
|
|
});
|
|
|
|
|
@ -659,32 +478,137 @@ public class TDengineService {
|
|
|
|
|
|
|
|
|
|
// 读取 query_data(二进制字段)
|
|
|
|
|
byte[] blob = rs.getBytes("query_data");
|
|
|
|
|
if (blob != null) {
|
|
|
|
|
// 转为字符串
|
|
|
|
|
String json = new String(blob, StandardCharsets.UTF_8).trim();
|
|
|
|
|
map.put("queryData", decodeQueryData(blob));
|
|
|
|
|
|
|
|
|
|
// 去除 TDengine 中可能存在的外层双引号
|
|
|
|
|
if (json.startsWith("\"") && json.endsWith("\"")) {
|
|
|
|
|
json = json.substring(1, json.length() - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果是十六进制字符串,先解码
|
|
|
|
|
if (isHexString(json)) {
|
|
|
|
|
json = hexToString(json);
|
|
|
|
|
}
|
|
|
|
|
return map;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 统一约定:queryData 始终返回 String,由上层决定是否解析 JSON
|
|
|
|
|
map.put("queryData", json);
|
|
|
|
|
} else {
|
|
|
|
|
// 没有数据时返回空数组字符串
|
|
|
|
|
map.put("queryData", "[]");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@DS("tdengine")
|
|
|
|
|
public List<Map<String, Object>> queryLastDataByHourBatch(
|
|
|
|
|
Set<Long> deviceIds,
|
|
|
|
|
LocalDateTime startTime,
|
|
|
|
|
LocalDateTime endTime) {
|
|
|
|
|
|
|
|
|
|
List<Map<String, Object>> result = new ArrayList<>();
|
|
|
|
|
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
|
|
|
|
|
|
|
for (Long deviceId : deviceIds) {
|
|
|
|
|
String sql =
|
|
|
|
|
"SELECT ts, query_data FROM besure.d_" + deviceId +
|
|
|
|
|
" WHERE ts >= '" + startTime.format(fmt) + "'" +
|
|
|
|
|
" AND ts <= '" + endTime.format(fmt) + "'" +
|
|
|
|
|
" ORDER BY ts ASC";
|
|
|
|
|
|
|
|
|
|
jdbcTemplate.query(sql, rs -> {
|
|
|
|
|
Map<String, Object> map = new HashMap<>();
|
|
|
|
|
map.put("deviceId", deviceId);
|
|
|
|
|
map.put("timestamp", rs.getTimestamp("ts").toLocalDateTime());
|
|
|
|
|
map.put("queryData", decodeQueryData(rs.getBytes("query_data")));
|
|
|
|
|
result.add(map);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@DS("tdengine")
|
|
|
|
|
public List<Map<String, Object>> queryLastDataByDaySafe(
|
|
|
|
|
Set<Long> deviceIds,
|
|
|
|
|
LocalDate startDate,
|
|
|
|
|
int days
|
|
|
|
|
) {
|
|
|
|
|
List<Map<String, Object>> result = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
DateTimeFormatter formatter =
|
|
|
|
|
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < days; i++) {
|
|
|
|
|
|
|
|
|
|
LocalDate day = startDate.plusDays(i);
|
|
|
|
|
LocalDateTime dayStart = day.atStartOfDay();
|
|
|
|
|
LocalDateTime dayEnd = day.plusDays(1).atStartOfDay();
|
|
|
|
|
|
|
|
|
|
for (Long deviceId : deviceIds) {
|
|
|
|
|
|
|
|
|
|
String tableName = "besure.d_" + deviceId;
|
|
|
|
|
|
|
|
|
|
String sql =
|
|
|
|
|
"SELECT ts, query_data FROM " + tableName +
|
|
|
|
|
" WHERE ts >= '" + dayStart.format(formatter) + "'" +
|
|
|
|
|
" AND ts < '" + dayEnd.format(formatter) + "'" +
|
|
|
|
|
" ORDER BY ts DESC LIMIT 1";
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
List<Map<String, Object>> rows = jdbcTemplate.query(
|
|
|
|
|
sql,
|
|
|
|
|
(rs, rowNum) -> {
|
|
|
|
|
Map<String, Object> map = new HashMap<>();
|
|
|
|
|
map.put("deviceId", deviceId);
|
|
|
|
|
map.put("day", day.toString());
|
|
|
|
|
|
|
|
|
|
Timestamp ts = rs.getTimestamp("ts");
|
|
|
|
|
map.put("timestamp",
|
|
|
|
|
ts != null ? ts.toLocalDateTime() : null);
|
|
|
|
|
|
|
|
|
|
byte[] blob = rs.getBytes("query_data");
|
|
|
|
|
map.put("queryData", decodeQueryData(blob));
|
|
|
|
|
|
|
|
|
|
return map;
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (!rows.isEmpty()) {
|
|
|
|
|
result.add(rows.get(0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
// 表不存在 / 查询失败 → 直接跳过
|
|
|
|
|
log.warn("Skip TDengine table: {}, reason: {}",
|
|
|
|
|
tableName, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return map;
|
|
|
|
|
});
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private String decodeQueryData(byte[] blob) {
|
|
|
|
|
if (blob == null || blob.length == 0) return "[]";
|
|
|
|
|
|
|
|
|
|
String json = new String(blob, StandardCharsets.UTF_8).trim();
|
|
|
|
|
|
|
|
|
|
// 去掉外层引号
|
|
|
|
|
if (json.startsWith("\"") && json.endsWith("\"")) {
|
|
|
|
|
json = json.substring(1, json.length() - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果是十六进制字符串,解码
|
|
|
|
|
if (isHexString(json)) {
|
|
|
|
|
json = hexToString(json);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return json;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|