我有一个JSON文件:
{
"settings": {
"header": {
"id": "240A64CDC43F",
"filename": "network",
"sequence": "0",
"last_modified": "2015-04-21T16:33",
"JSON_file_version": "2.1"
},
"data": {
"engine_config": {
"bed_name": "IdealTempCDC43F",
"provisioned": "false",
"connected": "false",
"IP_address": "192.168.10.1",
"connection_error": "None"
},
"networks": {
"available": "7",
"SSIDs": {
"wireless_1": {
"SSID": "$$ASI_WIFI$$",
"mac_address": "A0:EC:F9:11:35:04",
"channel": "11",
"RSSI": "-64dBm",
"security": "true",
"security_type": "WPA"
},
"wireless_2": {
"SSID": "$$ASI_GUEST$$",
"mac_address": "A0:EC:F9:11:35:02",
"channel": "11",
"RSSI": "-65dBm",
"security": "true",
"security_type": "WPA"
}
}
}
}
}
}
为了解析这个json我正在使用它:
HttpResponse response = client.execute(request);
String strResponse = response.toString();
parseJSON(strResponse);
和
public void parseJSON(String jsonString) {
Gson gsonParser = new Gson();
ProveQuerySetting gsonResponse = new ProveQuerySetting();
Type collectionType = new TypeToken<Collection<ProveQuerySetting>>() {
}.getType();
gsonResponse = gsonParser.fromJson(jsonString, collectionType);
String str = gsonParser.toJson(gsonResponse);
System.out.println(" final json " + str);
}
但我得到了这个例外:
04-21 07:08:13.864: W/System.err(4187): com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 1 path $
04-21 07:08:13.864: W/System.err(4187): com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 1 path $
04-21 07:08:13.865: W/System.err(4187): at com.google.gson.Gson.fromJson(Gson.java:822)
04-21 07:08:13.865: W/System.err(4187): at com.google.gson.Gson.fromJson(Gson.java:775)
04-21 07:08:13.865: W/System.err(4187): at com.google.gson.Gson.fromJson(Gson.java:724)
04-21 07:08:13.865: W/System.err(4187): at com.easi.main.network.NetworkCom.parseJSON(NetworkCom.java:127)
04-21 07:08:13.865: W/System.err(4187): at com.easi.main.network.NetworkCom.sendFirst(NetworkCom.java:50)
04-21 07:08:13.865: W/System.err(4187): at com.easi.main.setting.ConnectToBox$MyAsyncTask.doInBackground(ConnectToBox.java:89)
04-21 07:08:13.865: W/System.err(4187): at com.easi.main.setting.ConnectToBox$MyAsyncTask.doInBackground(ConnectToBox.java:1)
04-21 07:08:13.865: W/System.err(4187): at android.os.AsyncTask$2.call(AsyncTask.java:288)
04-21 07:08:13.865: W/System.err(4187): at java.util.concurrent.FutureTask.run(FutureTask.java:237)
04-21 07:08:13.865: W/System.err(4187): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
04-21 07:08:13.865: W/System.err(4187): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
04-21 07:08:13.865: W/System.err(4187): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
04-21 07:08:13.865: W/System.err(4187): at java.lang.Thread.run(Thread.java:818)
04-21 07:08:13.865: W/System.err(4187): Caused by: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 1 path $
04-21 07:08:13.865: W/System.err(4187): at com.google.gson.stream.JsonReader.beginArray(JsonReader.java:350)
04-21 07:08:13.866: W/System.err(4187): at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:79)
04-21 07:08:13.866: W/System.err(4187): at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:60)
04-21 07:08:13.866: W/System.err(4187): at com.google.gson.Gson.fromJson(Gson.java:810)
04-21 07:08:13.866: W/System.err(4187): ... 12 more
这是我的POJO课程:
public class ProveQuerySetting {
ProvQueryData provEngnData;
ProvQueryHeader provEngnhHeader;
public ProvQueryData getProvEngnData() {
return provEngnData;
}
public void setProvEngnData(ProvQueryData provEngnData) {
this.provEngnData = provEngnData;
}
public ProvQueryHeader getProvEngnhHeader() {
return provEngnhHeader;
}
public void setProvEngnhHeader(ProvQueryHeader provEngnhHeader) {
this.provEngnhHeader = provEngnhHeader;
}
}
为什么我会收到此异常?
答案 0 :(得分:1)
好的,所以你试图使用默认的Gson。大!默认的Gson很聪明,但不是那么聪明。您必须将类设计为完全匹配您要获取的json的格式,或者如果您不想设计自定义反序列化器,则使用@SerializedName
注释。当我说完全匹配时,我的意思是,字段名称必须与序列化Gson完全相同,无论是在字段名称还是注释中。
我创建了以下POJO(包括您的POJO,带有修改的字段名称)。为简洁起见,我没有包含getters / setter:
public class ProvEngineConfig {
private String bed_name;
private String provisioned;
private String connected;
private String IP_Address;
private String connection_error;
}
public class ProvNetworks {
private String available;
private Map<String, ProvSSID> SSIDs; // Notice this is a map
}
public class ProveQuerySetting {
ProvQueryData data;
ProvQueryHeader header;
}
public class ProvQueryData {
ProvEngineConfig engine_config;
ProvNetworks networks;
}
public class ProvQueryHeader {
String id;
String filename;
String sequence;
String last_modified;
String JSON_file_version;
}
public class ProvSSID {
String SSID;
String mac_address;
String channel;
String RSSI;
String security;
String security_type;
}
同样,您是否看到字段名称完全与JSON中的字段名称相同?请注意,在ProvNetworks
中,我正在使用地图,因为您提供的JSON是无线名称的地图,以完全匹配SSID对象。
我的POJO设置如下,请注意您提供的JSON不是Collection
的查询设置,实际上是Map<String, ProvQuerySetting>
,您可以从单词"settings"
映射到引擎配置对象。所以我这样解析它:
public static void parseJSON(String jsonString) {
Gson gsonParser = new Gson();
Map<String, ProveQuerySetting> gsonResponse; // You don't need to do new here
Type collectionType = new TypeToken<Map<String, ProveQuerySetting>>() {}.getType();
gsonResponse = gsonParser.fromJson(jsonString, collectionType);
String str = gsonParser.toJson(gsonResponse);
System.out.println(" final json " + str);
}
输出:
final json {"settings":{"data":{"engine_config":{"bed_name":"IdealTempCDC43F","provisioned":"false","connected":"false","connection_error":"None"},"networks":{"available":"7","SSIDs":{"wireless_1":{"SSID":"$$ASI_WIFI$$","mac_address":"A0:EC:F9:11:35:04","channel":"11","RSSI":"-64dBm","security":"true","security_type":"WPA"},"wireless_2":{"SSID":"$$ASI_GUEST$$","mac_address":"A0:EC:F9:11:35:02","channel":"11","RSSI":"-65dBm","security":"true","security_type":"WPA"}}}},"header":{"id":"240A64CDC43F","filename":"network","sequence":"0","last_modified":"2015-04-21T16:33","JSON_file_version":"2.1"}}}
您需要:
JsonReader
答案 1 :(得分:0)
Gson API很好,但我发现另一个API Jackson更强大且用户友好。需要两个jar文件jackson-core-asl-1.8.5和jackson-mapper-asl-1.8.5 然后
ObjectMapper mapper = new ObjectMapper();
MAinpojo object = null;
System.out.println("json string "+jsonString.trim());
try {
object = mapper.readValue(new URL("http://192.168.xx.x/pmmm-zzzz"), MAinpojo.class);
} catch (JsonParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
最后但并非最不重要的是关心你的POJO课程。
1.字段名称应该相同。
2.如果在某个字段中出现无法识别的异常,请使用此类注释
@JsonIgnoreProperties(ignoreUnknown=true)
public class MAinpojo {
@JsonProperty("settings")
ProveQuerySetting settings;
@JsonProperty("settings")
public ProveQuerySetting getSettings() {
return settings;
}
public void setSettings(ProveQuerySetting settings) {
this.settings = settings;
}
}
在所有字段之上,可能会抛出异常。