【问题标题】:Gson deserialisation generates NULL valueGson 反序列化生成 NULL 值
【发布时间】:2017-06-12 20:38:19
【问题描述】:

我试图读取 JSON 文件并将其转换为数组,但在读取 JSON 文件后从数组中获取空​​值。我正在为 ShipDetail 类使用默认构造函数。

  BufferedReader detailReader = new BufferedReader( new  FileReader(shipDetails));
  // Buffered passed to convert json array to java array
  ShipDetail[] shipDetail  = gson.fromJson(detailReader, ShipDetail[].class );

  System.out.println( shipDetail[0].toString());

  // Convert  array to arrayList
  ArrayList<ShipDetail> detailArray = new ArrayList<ShipDetail>(Arrays.asList(shipDetail));

JSON 文件:

[  
   {  
      "idmessage":"27301",
      "idsession":"362",
      "time_stamp_system":"2017-01-20 14:51:14",
      "NMEA_string":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "processed":"1",
      "MMSI":"0000000001",
      "AIS_version":"0",
      "IMO_number":"xxxxxxxxxx",
      "callSign":"ODLK1",
      "name":"ODLXJ KWW",
      "type_of_ship_and_cargo":"0",
      "bow_to_possition_unit":"212",
      "stern_to_possition_unit":"71",
      "port_to_possition_unit":"22",
      "starboard_to_possitio_unit":"22",
      "type_of_position_fixing_divice":"1",
      "ETA":null,
      "destination":"",
      "last_static_draught":"0",
      "DTE":"127"
   }
]

ShipDetail 类:

public class ShipDetail {

    private String IdMessage, IdSession, Time_Stamp_System, Nmea_String, Processed;
    private String Mmsi, Ais_Version, Imo_Number, Callsign, Name, Type_Of_Ship_And_Cargo;
    private String Bow_To_Position_Unit, Stern_To_Position_Unit, Port_To_Position_Unit, Starboard_To_Position_Unit,
            Type_Of_Position_Fixing_Device;
    private String Eta, Destination, Last_Ship_Draught, Dte;

    public String getMmsi() {
        return Mmsi;
    }

    public String toString() {
        return "\n Id Message : " + IdMessage + "\n Id Session : " + IdSession + "\n Time Stam System : "
                + Time_Stamp_System + "\n NMEA String : " + Nmea_String + "\n Processed : " + Processed + "\n MMSI : "
                + Mmsi + "\n AIS Version : " + Ais_Version + "\n IMO Number : " + Imo_Number + "\n Call Sign : "
                + Callsign + "\n Name : " + Name + "\n Type Of Ship And Cargo : " + Type_Of_Ship_And_Cargo
                + "\n Bow To Position Unit : " + Bow_To_Position_Unit + "\n Stern To Position Unit : "
                + Stern_To_Position_Unit + "\n Port To Position Unit : " + Port_To_Position_Unit
                + "\n Starboard To Position Fixing Device : " + Starboard_To_Position_Unit
                + "\n Type Of Position Fixing Device : " + Type_Of_Position_Fixing_Device + "\n ETA : " + Eta
                + "\n Destination : " + Destination + "\n Last Ship Draught : " + Last_Ship_Draught + "\n DTE : " + Dte;
    }
}

【问题讨论】:

  • 你能显示json文件吗?还有 ShipDetail 的外观,它是否有构造函数、get 和 set 方法,是否重写了 toString 方法以便使用它?
  • 我使用的是默认构造函数,并且我已经覆盖了 toString( ) 方法。
  • 你还需要生成getter和setter。你的文件是private。此外,在将事物直接映射到 Object 时,您需要使用 getter 和 setter,大多数库都需要它们。
  • 和声明public而不是private一样吗?
  • 没有。将 SQL 或 JSON 或 XML 映射到 java 对象的自定义库的实现正在寻找 GET 和 SET 方法。这就是它们的实施方式。他们会这样做:object.setField1(someValue) 而不是 object.field1 = someValue

标签: java arrays json arraylist gson


【解决方案1】:

您的 Gson 映射与给定的 JSON 不匹配。默认情况下,Gson 通过 exact 名称将 JSON 属性映射到目标映射中的相应字段。看看:

"idmessage":"27301"

private String IdMessage

属性名称大小写和字段名称大小写不匹配。您需要的是正确映射您的 JSON。要么:

private String idmessage

或通过覆盖名称匹配(这更适合 Java 命名约定):

@SerializedName("idmessage")
private String idMessage;

注意每行一个字段。这是为了分别注释每个字段所必需的。或者,如果可能,在 Java 和 JSON 中都使用 camelCase。

【讨论】:

  • @Anny 如果此答案解决了您的问题,请不要忘记接受并投票。 stackoverflow.com/help/someone-answers
  • 但我唯一没有得到的是为所有变量声明 String one's 和为每个变量声明 String 类型之间的区别。为什么图书馆需要这样的方式?
  • @Anny 1:它极大地增加了代码的可读性。 2:带注释的声明会影响声明中的所有字段,就好像已将注释应用于每个字段一样,因此Gson会抛出异常:java.lang.IllegalArgumentException: class ShipDetail declares multiple JSON fields named idmessage
  • 非常感谢:
  • @Anny 为每个声明保留单个属性的另一个优点:Git、SVN 等版本跟踪系统使用逐行差异算法来跟踪内容更改。因此,如果您将所有内容都放在一行中,则差异会很丑陋。但是一旦你把所有东西都分开了,你的差异会更容易阅读,并且在必要时更容易合并,因为如果两个分支中的 same 行发生更改,合并它们会导致文本冲突很高兴修复有太多字段。只是务实的观点。
【解决方案2】:

您可以按照这些思路使用一些东西。请注意,您不必使用Files.readAllBytes,但在您的代码中,BufferedReader 也可能导致错误。如果您需要 ShipDetails 作为数组而不是列表,请将其转换或在 TypeToken 中使用您需要的类型。

final GsonBuilder builder = new GsonBuilder();
final Gson gson = builder.enableComplexMapKeySerialization().create();

// you can use the buffered reader here too, but this is easier to debug if shipDetails is a file
final String jsonRepresentation = new String(Files.readAllBytes(shipDetails);

// add a type definition
final Type type = new TypeToken<ArrayList<ShipDetail>>(){}.getType();
ArrayList<ShipDetail> shipDetails = gson.fromJson(jsonRepresentation, type);

如上面的 cmets 所述,生成 Getter 和 Setter。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-06
    • 2011-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多