我正在制作一个Android应用程序来远程管理Unix计算机。该应用程序还允许您查看实时PC统计数据(CPU温度、CPU负载等)。在pc上有一个Python服务器,它通过套接字将JSON字符串作为字节数组发送到包含PC统计数据的应用程序,如下所示:
[123, 45, 67, 90, ...]这是字节数组的内容(我用一个网站解码的):
{
"author": "Anton",
"type": "server info",
"date": "08/01/2021",
"content": "",
"opt": {
"cpu": {
"freq": [3866.041875, 1600.0, 3900.0],
"usage": [0.0, 0.0, 1.0, 2.0, 1.0, 1.0, 0.0, 2.0],
"load": [0.5, 0.63, 0.61]
},
"memory": {
"ram": [15.54, 12.01, 22.7, 2.85, 9.67]
},
"disks": {
"ssd": [219.1, 13.0, 194.9, 6.3],
"hdd": [0.0, 0.0, 0, 100.0]
},
"temps": {
"core-0": [32.0, 85.0, 105.0],
"core-1": [36.0, 85.0, 105.0],
"core-2": [37.0, 85.0, 105.0],
"core-3": [38.0, 85.0, 105.0]
}
},
"attached": null
}如何将字节数组转换为HashMap或JSON字符串等结构,以便检索PC统计数据,并通过ProgressiveBars在App中查看?
发布于 2021-01-09 01:01:13
您应该能够使用Jackson的ObjectMapper或任何其他JSON解析器/序列化程序来实现这一点。一种选择是使用ObjectMapper将字符串直接序列化为哈希图,如下所示:
byte src[] = getBytesFromServer();
ObjectMapper om = new ObjectMapper();
TypeReference<Map<String,Object>> tr = new TypeReference<Map<String,Object>> {};
Map<String,Object> val = om.readValue(src,tr);这里有一些对你有帮助的变种。您也可以使用其他JSON库(如GSon )来实现相同的功能
发布于 2021-01-09 20:20:17
同时,虽然您的服务器代码尚未修复,但我可以提供一个示例,使字节编码的响应适应您可以解析的内容,以达到“教育”的目的,以避免将来出现不良实践(只需不做以下操作)。
解决问题的方法是将传入的有效负载(字节数组编码的文本)调整为可以作为JSON使用的字节/字符流。
使用org.json is可能是这样实现的(但是,我不确定我是否正确地实现了它):
public final class Decoding {
private Decoding() {
}
public static Reader of(final Reader reader) {
final JSONTokener jsonTokener = new JSONTokener(reader);
return new Reader() {
private boolean beginToProcess = true;
private boolean endToProcess = true;
@Override
public int read(@Nonnull final char[] buffer, final int offset, final int length)
throws IOException {
if ( beginToProcess ) {
final char ch = jsonTokener.nextClean();
if ( ch != '[' ) {
throw new IOException("Not an array begin: " + ch);
}
beginToProcess = false;
}
if ( !jsonTokener.more() ) {
if ( endToProcess ) {
final char ch = jsonTokener.nextClean();
if ( ch != '\u0000' ) {
throw new IOException("Not an array or document end: " + ch);
}
endToProcess = false;
}
return -1;
}
final char b = (char) (int) jsonTokener.nextValue();
if ( jsonTokener.more() ) {
final char ch = jsonTokener.nextClean();
switch ( ch ) {
case ',':
case ']':
// do nothing
break;
default:
throw new IOException("Not an array delimiter: " + ch);
}
}
buffer[offset] = b;
return 1;
}
@Override
public void close()
throws IOException {
reader.close();
}
};
}
...或者使用Gson,例如:
...
public static Reader of(final JsonReader jsonReader) {
return new Reader() {
private boolean beginToProcess = true;
private boolean endToProcess = true;
@Override
public int read(@Nonnull final char[] buffer, final int offset, final int length)
throws IOException {
if ( beginToProcess ) {
jsonReader.beginArray();
beginToProcess = false;
}
if ( !jsonReader.hasNext() ) {
if ( endToProcess ) {
jsonReader.endArray();
endToProcess = false;
}
return -1;
}
final int b = jsonReader.nextInt();
buffer[offset] = (char) b;
return 1;
}
@Override
public void close()
throws IOException {
jsonReader.close();
}
};
}
}这两个解码器都不是最优的,没有提供最高的性能,但我希望一旦你的服务器修复了,你就不需要它了。现在您可以解码输入读取器并将其转换为有效的JUnit文档(在JSON 5测试中):
public final class DecodingTest {
@Test
public void test()
throws IOException {
final String payload = "[123,34,97,117,116,104,111,114,34,58,34,65,110,116,111,110,34,44,34,116,121,112,101,34,58,34,115,101,114,118,101,114,32,105,110,102,111,34,44,34,100,97,116,101,34,58,34,48,56,47,48,49,47,50,48,50,49,34,44,34,99,111,110,116,101,110,116,34,58,34,34,44,34,111,112,116,34,58,123,34,99,112,117,34,58,123,34,102,114,101,113,34,58,91,51,56,54,54,46,48,52,49,56,55,53,44,49,54,48,48,44,51,57,48,48,93,44,34,117,115,97,103,101,34,58,91,48,44,48,44,49,44,50,44,49,44,49,44,48,44,50,93,44,34,108,111,97,100,34,58,91,48,46,53,44,48,46,54,51,44,48,46,54,49,93,125,44,34,109,101,109,111,114,121,34,58,123,34,114,97,109,34,58,91,49,53,46,53,52,44,49,50,46,48,49,44,50,50,46,55,44,50,46,56,53,44,57,46,54,55,93,125,44,34,100,105,115,107,115,34,58,123,34,115,115,100,34,58,91,50,49,57,46,49,44,49,51,44,49,57,52,46,57,44,54,46,51,93,44,34,104,100,100,34,58,91,48,44,48,44,48,44,49,48,48,93,125,44,34,116,101,109,112,115,34,58,123,34,99,111,114,101,45,48,34,58,91,51,50,44,56,53,44,49,48,53,93,44,34,99,111,114,101,45,49,34,58,91,51,54,44,56,53,44,49,48,53,93,44,34,99,111,114,101,45,50,34,58,91,51,55,44,56,53,44,49,48,53,93,44,34,99,111,114,101,45,51,34,58,91,51,56,44,56,53,44,49,48,53,93,125,125,44,34,97,116,116,97,99,104,101,100,34,58,110,117,108,108,125]";
final String expected = "{\"author\":\"Anton\",\"type\":\"server info\",\"date\":\"08/01/2021\",\"content\":\"\",\"opt\":{\"cpu\":{\"freq\":[3866.041875,1600,3900],\"usage\":[0,0,1,2,1,1,0,2],\"load\":[0.5,0.63,0.61]},\"memory\":{\"ram\":[15.54,12.01,22.7,2.85,9.67]},\"disks\":{\"ssd\":[219.1,13,194.9,6.3],\"hdd\":[0,0,0,100]},\"temps\":{\"core-0\":[32,85,105],\"core-1\":[36,85,105],\"core-2\":[37,85,105],\"core-3\":[38,85,105]}},\"attached\":null}";
try ( final Reader reader = Decoding.of(new StringReader(payload));
final Writer writer = new StringWriter() ) {
CharStreams.copy(reader, writer);
Assertions.assertEquals(expected, writer.toString());
}
try ( final Reader reader = Decoding.of(new JsonReader(new StringReader(payload)));
final Writer writer = new StringWriter() ) {
CharStreams.copy(reader, writer);
Assertions.assertEquals(expected, writer.toString());
}
}
}请注意,CharStreams.copy是从Google Guava中提取出来的。
阅读器现在可以作为常规JSON文档由库、org.json、Gson、Jackson、Moshi或其他任何文档使用。
https://stackoverflow.com/questions/65631929
复制相似问题