简体   繁体   中英

Parse Json using gson

I have current JSON structure. This is nothing more than list of objects.

{
    "response": {
        "wall": [366,
        {
            "id": 727,
            "from_id": 21454540,
            "to_id": 52158932,
            "date": 1384634706,
            "post_type": "post",
            "text": "",
            "can_delete": 1,
            "media": {
                "type": "photo",
                "owner_id": 21454540,
                "item_id": 314573297,
                "thumb_src": "http:\/\/cs313417.vk.me\/v313417540\/6cc9\/Ze-8KY9tYfc.jpg"
            },
            "attachment": {
                "type": "photo",
                "photo": {
                    "pid": 314573297,
                    "aid": -5,
                    "owner_id": 21454540,
                    "src": "http:\/\/cs313417.vk.me\/v313417540\/6cc9\/Ze-8KY9tYfc.jpg",
                    "src_big": "http:\/\/cs313417.vk.me\/v313417540\/6cca\/ndKUage2w4I.jpg",
                    "src_small": "http:\/\/cs313417.vk.me\/v313417540\/6cc8\/A5m7zXxTAlQ.jpg",
                    "src_xbig": "http:\/\/cs313417.vk.me\/v313417540\/6ccb\/gaW8MQhFiFQ.jpg",
                    "width": 760,
                    "height": 606,
                    "text": "",
                    "created": 1384634699,
                    "access_key": "bafb734c3dd74c5656"
                }
            },
            "attachments": [{
                "type": "photo",
                "photo": {
                    "pid": 314573297,
                    "aid": -5,
                    "owner_id": 21454540,
                    "src": "http:\/\/cs313417.vk.me\/v313417540\/6cc9\/Ze-8KY9tYfc.jpg",
                    "src_big": "http:\/\/cs313417.vk.me\/v313417540\/6cca\/ndKUage2w4I.jpg",
                    "src_small": "http:\/\/cs313417.vk.me\/v313417540\/6cc8\/A5m7zXxTAlQ.jpg",
                    "src_xbig": "http:\/\/cs313417.vk.me\/v313417540\/6ccb\/gaW8MQhFiFQ.jpg",
                    "width": 760,
                    "height": 606,
                    "text": "",
                    "created": 1384634699,
                    "access_key": "bafb734c3dd74c5656"
                }
            }],
            "post_source": {
                "type": "vk"
            },
            "comments": {
                "count": 0,
                "can_post": 1
            },
            "likes": {
                "count": 1,
                "user_likes": 0,
                "can_like": 1,
                "can_publish": 0
            },
            "reposts": {
                "count": 0,
                "user_reposted": 0
            },
            "online": 0,
            "reply_count": 0
        },
        {
            ....
            ....
        }]
    }
}

I want to use GSON to parse it into JAVA objects. I have created a Wall java class to store all information about object. Also current response contains information about total quantity of those objects on server side. Number 366 . (Note this is not a length of list in response, this is total number records on server side) I am really confused what to do about it?

Question: How my java model class should look like in order to successfully deserialize objects and total number of records? I want response to be serialized into something like:

public class WallResponse
{
  private int totalRecords;
  private List<Wall> wallRecordsList;

  //getters and setters
}

Thanks a lot!!!

JSONGen可能对生成对象很有用,请注意,对于更具体的类型,可能需要一些手工制作,但这肯定是一个好的开始。

In your json fromat the JSON array contains mixed types. Deserialization with fromJson() will not work since Gson has no way of knowing how to map the input to the types. Gson requires that you provide a genericised version of collection type in fromJson. So, you have three options:

Option 1: Use Gson's parser API.

Option 2: Register a type adapter for Collection.class.

Option 3: Register a type adapter for MyCollectionMemberType. This approach is practical only if the array appears as a top-level element. Here in your case option 3 is best because array is on the top level elements of response object. I've followed mixed approach option 1 & 3.

For further detail see Serializing and Deserializing Collection with Objects of Arbitrary Types using Gson Gson Collections Limitations

The complex part in your json format is deserialize total record number
 in Wall class object

Here is the tricky part to deserialize the json in java objects.

GsonBuilder b = new GsonBuilder();

b.registerTypeAdapter(WallResponse.class,new JsonDeserializer<WallResponse>() {

@Override
public WallResponse deserialize(JsonElement jsonElement,Type typeOf, JsonDeserializationContext context)  throws JsonParseException {

    final Gson g = new Gson();

    final JsonObject jsonObject = jsonElement.getAsJsonObject();

    final WallResponse wallResponse = new WallResponse(new Response());                                         
    final Entry<String, JsonElement> entry = jsonObject.entrySet().iterator().next();
    final JsonElement element = entry.getValue();
    final JsonObject jsonObject2 = element.getAsJsonObject();

    final Entry<String, JsonElement> entry2 = jsonObject2.entrySet().iterator().next();
    final JsonArray jsonArray = entry2.getValue().getAsJsonArray();
    final Iterator<JsonElement> jsonElement2 = jsonArray.iterator();
    int totalRecord=-1;

    while (jsonElement2.hasNext()) {
        final JsonElement element2 = jsonElement2.next();
        if (element2.isJsonPrimitive())
            totalRecord=element2.getAsInt();
        if (element2.isJsonObject()) {
            final Wall wall = g.fromJson(element2, Wall.class);
            wall.setTotalRecord(totalRecord);
            List<Wall> walls= new ArrayList<>();
            walls.add(wall);
            wallResponse.getResponse().setWall(walls);
        }
    }


    return wallResponse;
  }
});

WallResponse response = b.create().fromJson(reader, WallResponse.class);

Java models classes are like below according to json format

WallResponse Class

public class WallResponse {

    private Response response;

    public WallResponse() { super();{

    public WallResponse(Response response) {super();this.response = response;}

    public Response getResponse() { return this.response;}

    public void setResponse(Response response) { this.response = response;  }

    @Override
    public String toString() { return "WallResponse [response=" + response + "]"; }

}

Response Class

 public class Response {

    private List<Wall> wall;

    public List<Wall> getWall() { return this.wall; }

    public void setWall(List<Wall> wall) {  this.wall = wall; }

    @Override
    public String toString() { return "Response [wall=" + wall + "]"; }
}

Wall Class

public class Wall {

    private int totalRecord;
    private Media media;
    private Attachment attachment;
    private List<Attachments> attachments;
    @SerializedName(value = "post_source")
    private PostSource postSource;
    private Comments comments;
    @SerializedName(value = "likes")
    private Like like;
    @SerializedName(value = "reposts")
    private Repost repost;

    private String id;
    private String from_id;
    private String to_id;
    private String date;
    private String post_type;
    private String text;
    private String can_delete;
    private String reply_count;
    private String online;

        // setter getter here
}

Media Class

public class Media {

    private String type;
    private String owner_id;
    private String item_id;
    private String thumb_src;
//setter getter here
        @Override
    public String toString() {
        return "Media [type=" + type + ", owner_id=" + owner_id + ", item_id="
                + item_id + ", thumb_src=" + thumb_src + "]";
    }
}

Attachment Class

public class Attachment {

    private String type;
    private Photo photo;
// setter getter here
    @Override
    public String toString() {
        return "Attachment [type=" + type + ", photo=" + photo + "]";
    }
}

Attachments

public class Attachments {

    private String type;
    private Photo photo;
// getter setter here
    @Override
    public String toString() {
        return "Attachment [type=" + type + ", photo=" + photo + "]";
    }
}

Photo Class composed by Attachment and Attachments class

public class Photo {

    private String pid;
    private String aid;
    private String owner_id;
    private String src;
    private String src_big;
    private String src_small;
    private String src_xbig;
    private String width;
    private String height;
    private String text;
    private String created;
    private String access_key;
// setter getter here
    @Override
    public String toString() {
        return "Photo [pid=" + pid + ", aid=" + aid + ", owner_id=" + owner_id
                + ", src=" + src + ", src_big=" + src_big + ", src_small="
                + src_small + ", src_xbig=" + src_xbig + ", width=" + width
                + ", height=" + height + ", text=" + text + ", created="
                + created + ", access_key=" + access_key + "]";
    }

}

Base Model Class for common properties in Comments,Report and Like class.

public class BaseModel {

    private String type;
    private int count;

    public void setType(String type) {  this.type = type; }
    public String getType() {return type;}
    public int getCount() { return count;}
    public void setCount(int count) {this.count = count;}

    @Override
    public String toString() {return "BaseModel [type=" + type + ", count=" + count + "]";}

}

Comments Class

public class Comments extends BaseModel {

    private String can_post;

    @Override
    public String toString() {
        return "Comments [count=" + getCount() + ", can_post=" + can_post + "]";
    }
}

Like Class

public class Like extends BaseModel {

    private int user_likes;
    private String can_like;
    private String can_publish;

    @Override
    public String toString() {
        return "Like [user_likes=" + user_likes + ", can_like=" + can_like
                + ", can_publish=" + can_publish + ", count =" + getCount()
                + "]";
    }
}

Report Class

public class Repost extends BaseModel {

    private String user_reposted;

    @Override
    public String toString() {
        return "Repost [user_reposted=" + user_reposted + ", count=" + getCount() + "]";
    }
}

Finally your object graph will look like this

// wallResponse object.
WallResponse [  // response object
              response=Response 
              [wall=   // wall object
                    [Wall [totalRecord=10, media=Media [type=photo, owner_id=21454540, item_id=314573297, thumb_src=http://cs313417.vk.me/v313417540/6cc9/Ze-8KY9tYfc.jpg], 
                           attachment=Attachment [type=photo, 
                                                   // photo object inside attachment    
                                                  photo=Photo [pid=314573297, aid=-5, owner_id=21454540, src=http://cs313417.vk.me/v313417540/6cc9/Ze-8KY9tYfc.jpg, src_big=http://cs313417.vk.me/v313417540/6cca/ndKUage2w4I.jpg, src_small=http://cs313417.vk.me/v313417540/6cc8/A5m7zXxTAlQ.jpg, src_xbig=http://cs313417.vk.me/v313417540/6ccb/gaW8MQhFiFQ.jpg, width=760, height=606, text=, created=1384634699, access_key=bafb734c3dd74c5656]], 
                           attachments=[Attachment [type=photo,  
                                                     // photo object inside attachements                           
                                                    photo=Photo [pid=314573297, aid=-5, owner_id=21454540, src=http://cs313417.vk.me/v313417540/6cc9/Ze-8KY9tYfc.jpg, src_big=http://cs313417.vk.me/v313417540/6cca/ndKUage2w4I.jpg, src_small=http://cs313417.vk.me/v313417540/6cc8/A5m7zXxTAlQ.jpg, src_xbig=http://cs313417.vk.me/v313417540/6ccb/gaW8MQhFiFQ.jpg, width=760, height=606, text=, created=1384634699, access_key=bafb734c3dd74c5656]]], 
                            // postSource object                        
                           postSource=PostSource [getType()=vk], 
                           // comments object
                           comments=Comments [count=0, can_post=1], like=Like [user_likes=0, can_like=1, can_publish=0, count =1], 
                           //report object
                           repost=Repost [user_reposted=0, count=0],
                           // wall data...
                           id=727, from_id=21454540, to_id=52158932, date=1384634706, post_type=post, text=, can_delete=1, reply_count=0, online=0]]]]

Enjoy! :)

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