2014-01-31 65 views
-1

我第一次使用GSON。我想将一个JSON字符串反序列化成一个自定义对象,但是我的对象的每个属性都设置为null。没有解析错误,所以我认为JSON属性没有映射到对象?GSON自定义对象反序列化将所有字段设置为空

这是我的代码,如果有人能指出我出错的地方,那将是非常感谢。我已经检查了所有对教程,并不能看到问题。唯一的问题是JSON字符串中的属性比在我的对象中多,但我希望这并不重要。

JSON字符串:

{ 
    "_id": "D7D4A7D8219CA25848257C63000A1B50", 
    "ReportingPerson": "TRAIN2 Ifap", 
    "InjuredPerson": "TRAIN3 Ifap", 
    "DateReported": { 
     "$date": "2014-01-17T00:00:00.000Z" 
    }, 
    "Company": "test", 
    "Division": "Learning & Development", 
    "Site_id": "3CA9AD4E6066388648257B7500047D90", 
    "Department_id": "724BC4B509E7B61648257363002FD645", 
    "Area": "Training Room", 
    "DocNo": "002223", 
    "CreatedBy": "Ifap TRAIN2", 
    "DateComposed": { 
     "$date": "2014-01-17T01:50:23.000Z" 
    }, 
    "OccurTime": "12:00:00", 
    "Affiliation": "Employee", 
    "BriefDescription": "Employee tripped over power lead in computer lab.", 
    "ThirdPartyInvolvedYN": "No", 
    "ThirdPartyName": "", 
    "ThirdPartyAddress": [ 
     "" 
    ], 
    "ThirdPartyTel": "", 
    "Classification": "Minor Injury", 
    "Confidential": "", 
    "ConfidentialMonitors": [ 
     "" 
    ], 
    "IncidentCategory": "2", 
    "IncidentCategoryPotential": "3", 
    "ReportableYN": "No", 
    "ExternalBody": [ 
     "" 
    ], 
    "Authorisor": "", 
    "WorkSafeConfirmedYN": "No", 
    "Details": "Fell over cord in computer lab when walking through. Held hand out to brace fall and fell on pinkie finger.", 
    "Controls": [ 
     "Tape over cord." 
    ], 
    "Witnesses": [ 
     "No" 
    ], 
    "Supervisor": "TRAIN1 Ifap", 
    "IntAuthorisor": "TRAIN3 Ifap", 
    "IntAuthorisorNext": "", 
    "AssociatedRisks": {}, 
    "OpenActions": {}, 
    "ClosedActions": {} 
} 

POJO:

public class Incident { 

     @SerializedName("_id") 
    private String _id; 
    private String docNo; 
    private String site_id; 
    private String company; 
    private String division; 
    private String department_id; 
    private Date dateReported; 
    private String briefDescription; 
    private String thirdPartyInvolvedYN; 
    private String supervisor; 
    private String classification; 
    private String status; 
    private String injuredPerson; 
    private String reportingPerson; 
    private Date occurDate; 
    private String occurTime; 

//Getters & Setters... 
} 

主要方法:

public Incident convertJSONToBean(String json) { 
     Incident i = new Incident(); 

      Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create(); 
     Type type = new TypeToken<Incident>(){}.getType(); 

     try { 
      i = gson.fromJson(json, type); 

     } catch (JsonSyntaxException e) { 
      e.printStackTrace(); 

     } catch (JsonIOException e) { 
      e.printStackTrace(); 

     } 

     return i; 

    } 

类型正确设置为Incident.class。但是,生成的事件对象的任何属性都是空的。

我试着注释掉除_id之外的所有属性,以查看是否可以只填充一个来填充它,但它仍然设置为null。

+0

对我的作品完美的罚款;您发布的代码没有任何问题。我会检查你提供给Gson的实际字符串。 –

+0

感谢您的检查。我尝试在convertJSONToBean方法内打印出json字符串,并且它都可以。属性仍然返回null。任何其他的想法......我很难过。 – jellybaby

回答

0

你有json字符串中有趣的日期对象。如;

"DateReported": { 
    "$date": "2014-01-17T00:00:00.000Z" 
} 

这会导致JsonParseException因为你Incident类:

com.google.gson.JsonParseException: The date should be a string value 

为了您Incident类,日期在JSON值应该是这样的;

"DateReported": "2014-01-17T00:00:00.000Z" 


如果您还没有一个选项以JSON值更改日期,那么你应该定义其自定义日期支持类:

public class CustomDateHolder { 
    @SerializedName("$date") 
    private Date date; 
    // Getters & Setters... 
} 

而改变这些日期字段键入到CustomDateHolder;

public class Incident { 
    @SerializedName("_id") 
    private String _id; 
    private String docNo; 
    private String site_id; 
    private String company; 
    private String division; 
    private String department_id; 
    private CustomDateHolder dateReported; 
    private String briefDescription; 
    private String thirdPartyInvolvedYN; 
    private String supervisor; 
    private String classification; 
    private String status; 
    private String injuredPerson; 
    private String reportingPerson; 
    private CustomDateHolder occurDate; 
    private String occurTime; 
    // Getters & Setters... 
} 

而且修改GsonBuilder一点点:

GsonBuilder gsonBuilder = new GsonBuilder(); 
gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE); 
gsonBuilder.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); 
Gson gson = gsonBuilder.create(); 
+0

我相信customDateHolder类是不需要的。使用@SerializedName可以遍历树。我现在不能做一个测试,但添加下面的注释到dateReported变量应该没有包装类:@SerializedName(“DateComposed。@ date”) – tom

+0

@tom SerializedName有一个选项吗? – Devrim

+0

我检查了一个项目,如果你用'。'分隔名称。它遍历树。 – tom

0

JSON格式DateComposed & DateReported性能对象,你需要创建 或者自定义模型类为他们或写CustomDeserializer类他们。

"DateComposed": { "$date": "2014-01-17T01:50:23.000Z" } 
"DateReported": {"$date": "2014-01-17T00:00:00.000Z"} 


public class Incident { 

    @SerializedName("_id") 
    private String _id; 
    @SerializedName(value = "ReportingPerson") 
    // other properties, you need to put @SerializedName on each property 
      ............ 
    // No need to put SerializedName annotation on dateReported & dateComposed 
    private Date dateReported; 
    private Date dateComposed; 

    @SerializedName(value = "ThirdPartyAddress") 
    private List<String> thirdPartyAddress; 
    @SerializedName(value = "ConfidentialMonitors") 
    private List<String> confidentialMonitors; 
    @SerializedName(value = "ExternalBody") 
    private List<String> externalBody; 
    @SerializedName(value = "Controls") 
    private List<String> controls; 
    @SerializedName(value = "Witnesses") 
    private List<String> witnesses; 
     // getter/setter 
      .... 
} 

下面是反序列化日期属性CustomDeserializer类

public class CustomDeserializer implements JsonDeserializer<Incident> { 

     @Override 
     public Incident deserialize(JsonElement json, Type type, 
       JsonDeserializationContext context) throws JsonParseException { 


      final JsonObject jsonObject = json.getAsJsonObject(); 

      final Gson gson = new Gson(); 
// Parse the JsonElement tree here 
      final Incident incident = gson.fromJson(json, Incident.class); 
// getting date properties as string from JsonElement and parse them into date object. 

      String dateReportedStr = jsonObject.get("DateReported").getAsJsonObject().get("$date").getAsString(); 
      String dateComposedStr = jsonObject.get("DateComposed").getAsJsonObject().get("$date").getAsString(); 
      DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); 

      try { 
// setting date properties in incident object 
       incident.setDateReported(df.parse(dateReportedStr)); 
       incident.setDateComposed(df.parse(dateComposedStr)); 
      } catch (ParseException e) { 
       e.printStackTrace(); 
      } 

      return incident; 
     } 
    } 

最后解析它

final GsonBuilder gsonBuilder = new GsonBuilder(); 
gsonBuilder.registerTypeAdapter(Incident.class, new CustomDeserializer()); 
Gson gson = gsonBuilder.create(); 
Incident incident = gson.fromJson(Your_JSON_STR, Incident.class); 
+0

感谢您的代码示例,这对于复制自定义解串器非常有用。 – jellybaby

相关问题