简体   繁体   中英

Android: JSON to objects using GSON fails

I'm a newbee to Android development and have a question about getting a JSON string transformed to class instances using GSON, version 2.6.1.

I have a need for transforming a string like this to objects:

{
"Messages": [{
    "ForwardMsg": true,
    "IsAdmin": true,
    "MsgBody": "Some text",
    "SysInfo": null,
    "Recipients": ["Some test"]
}, {
    "ForwardMsg": true,
    "IsAdmin": false,
    "MsgBody": "Some other text",
    "SysInfo": null,
    "Recipients": ["Some test", "Some more text"]
}]
}

With this ( http://howtodoinjava.com/best-practices/google-gson-tutorial-convert-java-object-to-from-json/ ) as inspiration, I've come up with the following: I have a class DemoMessageList that looks like this:

import java.util.List;

public class DemoMessageList {

private List< DemoMessage> messages;

public DemoMessageList () {
}

public List< DemoMessage > getMessages() {
    return messages;
}

public void setMessages(List< DemoMessage > messages) {
    this.messages = messages;
}

@Override
public String toString()
{
    return "Messages ["+ messages + "]";
}
}

And a class DemoMessage that looks like this:

import java.util.List;

public class DemoMessage {
private Boolean forwardMsg;
private Boolean isAdmin;
private String msgBody;
private String sysInfo;
private List<String> recipients;

public Boolean getForwardMsg() {
    return forwardMsg;
}

public void setForwardMsg(Boolean forwardMsg) {
    this.forwardMsg = forwardMsg;
}

public Boolean doForwardMsg() {
    return forwardMsg;
}

public Boolean getIsAdmin() {
    return isAdmin;
}

public void setIsAdmin(Boolean isAdmin) {
    this.isAdmin = isAdmin;
}

public String getMsgBody() {
    return msgBody;
}

public void setMsgBody(String msgBody) {
    this.msgBody = msgBody;
}

public String getSysInfo() {
    return sysInfo;
}

public void setSysInfo(String sysInfo) {
    this.sysInfo = sysInfo;
}

public List<String> getRecipients() {
    return recipients;
}

public void setRecipients(List<String> recipients) {
    this.recipients = recipients;
}
}

When I do this, to try transform:

public void test() {
String demoData = {"Messages": [{ "ForwardMsg": true, "IsAdmin": false,"MsgBody": "Some other text", "SysInfo": null, "Recipients": ["Some test", "Some more text"]}]}
Log.d("AsData ", "demoData: " + demoData);
Gson gson = new Gson();
DemoMessageList dmList = gson.fromJson(demoData, DemoMessageList.class);
Log.d("AsList ", "dmList: " + dmList.toString());
Log.d("ListSize ", "dmList - Size: " + String.valueOf(dmList.getMessages().size()));
}

I get this logged:

demoData: {"Messages": [{ "ForwardMsg": true, "IsAdmin": false, "MsgBody": "Some other text", "SysInfo": null, "Recipients": ["Some test", "Some more text"]}]}
dmList: Messages [null]
dmList - Size: 0

Why does this fail?? Please help!!!

Your JSON names are different from your class field names. GSON looks at your field names for transformation.

Use your model class like this with custom naming,

@SerializedName("ForwardMsg")
private Boolean forwardMsg;
@SerializedName("IsAdmin")
private Boolean isAdmin;
@SerializedName("MsgBody")
private String msgBody;
@SerializedName("SysInfo")
private String sysInfo;
@SerializedName("Recipients")
private List<String> recipients;

and keep your other class ,

@SerializedName("Messages")
private List< DemoMessage> messages;

Use camel case on your JSON property names:

{
"messages": [{
    "forwardMsg": true,
    "isAdmin": true,
    "msgBody": "Some text",
    "sysInfo": null,
    "recipients": ["Some test"]
}, {
    "forwardMsg": true,
    "isAdmin": false,
    "msgBody": "Some other text",
    "sysInfo": null,
    "recipients": ["Some test", "Some more text"]
}]
}

.. and make the fieldnames match the case of the JSON property names, eg:

private List<DemoMessage> messages;

In short: The JSON property names must match the fields defined in your class(es), both by spelling and letter case.

You rock guys!!

Bharath Mg' answer works perfect in my little test, when adding this:

import com.google.gson.annotations.SerializedName;

I have no control over the string containing the JSON in the real world application as it is provided by a webservice.

This has been bugging me for the 2 days, so I look forward to get on with project.

Thanks again

Bharat's answer is correct. Fields names are case-sensitive.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM