GSON自定义对象反序列化将所有字段设置为null

时间:2014-01-31 06:44:35

标签: java json gson

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

这是我的代码,如果有人能指出我出错的地方,我将不胜感激。我已经检查了一切反对教程,无法看到问题。唯一的问题是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。但是生成的Incident对象的任何属性都是null。

我尝试注释除了_id之外的所有属性,看看我是否只能填充一个但仍然设置为null。

2 个答案:

答案 0 :(得分: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();

答案 1 :(得分:0)

以Json格式DateComposed&amp; DateReported属性是Object,您需要创建 为他们定制模型类或为他们编写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);