Java 为什么我得到一个JsonSyntaxException:应该是BEGIN\u数组,但这里是字符串?

Java 为什么我得到一个JsonSyntaxException:应该是BEGIN\u数组,但这里是字符串?,java,android,json,exception,gson,Java,Android,Json,Exception,Gson,我有一个JSON文件: { "settings": { "header": { "id": "240A64CDC43F", "filename": "network", "sequence": "0", "last_modified": "2015-04-21T16:33", "JSON_file_version": "2.1" }, "data": { "engine_con

我有一个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);

这是我的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;
  }
}

为什么会出现此异常?

好的,您正在尝试使用默认的Gson。伟大的默认的Gson是smart,但不是那么smart。如果不想设计自定义反序列化程序,则必须将类设计为与要返回的json格式完全匹配,或者使用注释。当我说完全匹配时,我的意思是,字段名必须与序列化Gson在字段名或注释中完全相同

我创建了以下POJO(包括您的POJO,并修改了字段名)。为了简洁起见,我没有包括getter/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;
}
输出:

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"}}}

总结如下: 您需要:

  • 精确地匹配POJO和字段名/注释字段名以匹配JSON
  • 编写自己的自定义反序列化程序,如中所述

  • Gson API很好,但我发现还有一个API更健壮、用户友好。需要两个jar文件jackson-core-asl-1.8.5和jackson-mapper-asl-1.8.5 然后

    最后但并非最不重要的一点是,要充分关注你的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;
        }
    
    }
    

    最重要的是,可能引发异常的字段。

    -不是有效的json。这是有效的json。为iOSI工作时,您可以使用发布的json,并使用验证。JSON在第1行的
    分析错误中不正确:{settings:{----------^应为'STRING','}'
    @BlueGreen-2站点独立地说它不是有效的JSON。iOS可能有可以处理它的错误处理,但它无效json@BlueGreen您是否会收到与此编辑的json相同的错误?“我的意思是,字段名必须与序列化的Gson完全相同。”如果您想遵守java编码约定,不一定可以使用注释
    @SerializedName
    。例如:
    @SerializedName(“json_name”)私有数据类型javaName;
    毫无疑问……您的建议帮助很大。我非常感谢您的努力。我还需要一个小帮助,即如何从“collectionType”获取数据。一个小提示就足够了。@durron597..现在数据被成功解析。我将如何在项目中使用解析后的数据进行查看
    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"}}}
    
    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();
        }
    
      @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;
        }
    
    }