且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Gson反序列化 - 试图将JSON解析为对象

更新时间:2023-01-17 15:52:03

使用Gson Deserializer类。它们非常简单:为了实现这个功能,你必须确保解析器不会尝试序列化侵权对象
(在这个例子中案例你的地图)。我会将你的地图对象重命名为_links或some,这样序列化程序将跳过它。和你的配置文件中的这个例子一样。



一旦你完成了,你必须反序列化它,并确保将反序列化器包含在gson对象中:

 用户u; 
GsonBuilder gb = new GsonBuilder();
gb.registerTypeAdapter(User.class,new UserDeserializer());
Gson g = gb.create();
u = g.fromJson(json,User.class);


public class UserDeserializer实现了JsonDeserializer< UserDeserializer>
{
@Override
public User deserialize(JsonElement json,Type typeOfT,JsonDeserializationContext context)
{
User u = g.fromJson(json,User.class) ;
JsonObject jo =(JsonObject)json;
JsonElement je = jo.get(links);
//遍历je元素来填充你的地图。
}

}


I am trying to parse a JSON into an Object. There are two classes: User and Profile. User got an instance of Profile.

So now there is one JSON to build an User Object. Inside this JSON are the attributes for the User and Profile listed and as you can see, Profile and User got both a HashMap called List. However i'd like to create the User and the Profile out of this Json, but i got this Exception:

//EDIT:

I removed the Map<String, String> links from Profile and User. So now I do not get any errors and every User got a Profile - but I still need those Maps. Is it possible that GSON cant differentiate between the two lists ressources inside of the json because they have the same name?

//Dirty Hack Solution: An ArrayList instead of the HashMap was no problem. However I decided to parse this part of the Json "by hand" to insert the Objects into my HashMap..

01-03 05:27:59.580: E/AndroidRuntime(4313): com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 12
01-03 05:27:59.580: E/AndroidRuntime(4313):     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:180)

User:

public class User {
    private String username;
    private String slug;
    private String email;
    private Boolean emailVerified;
    private Profile profile;
    Map<String, String> links;
    public User()
    {
        this.username = null;
        this.slug = null;
        this.email = null;
        this.emailVerified = null;
        this.profile = null;
        this.links = new HashMap<String, String>();
    }

    public String getUsername(){
        return this.username;
    }

    public String getSlug(){
        return this.slug;
    }

    public String getEmail(){
        return this.email;
    }

    public Boolean getEmailVerified(){
        return this.emailVerified;
    }

    public Profile getProfile(){
        return this.profile;
    }
}

Profile:

public class Profile {

    private Map<String, String> links;
    private String name;
    private String description;
    private String gender;
    private String status;
    private String timezone;
    private Bitmap icon;

    public Profile()
    {
        this.name = null;
        this.description = null;
        this.gender = null;
        this.status = null;
        this.timezone = null;
        this.links = new HashMap<String, String>();
    }

    public String getName(){
        return this.name;
    }

    public String getDescription(){
        return this.description;
    }

    public String getGender(){
        return this.gender;
    }

    public String getStatus(){
        return this.status;
    }

    public String getTimezone(){
        return this.timezone;
    }
}

An example JSON:

{ "email" : "foo@bar.com",
  "emailVerified" : true,
  "links" : [ { "href" : "http://xxx.de/api/users/4f3a73004bb67751bc000011",
        "rel" : "self"
      },
      { "href" : "http://xxx.de:/api/users/4f3a73004bb67751bc000011/followers",
        "rel" : "https://xxx.com/rels/collection/follower"
      },
      { "href" : "http://xxx.de/api/users/4f3a73004bb67751bc000011/friends",
        "rel" : "https://xxx.com/rels/collection/friend"
      },
      { "href" : "http://xxx.de/api/users/4f3a73004bb67751bc000011/activity_stream",
        "rel" : "https://xxx.com/rels/activity_stream"
      }
    ],
  "profile" : { "description" : "",
      "gender" : "male",
      "links" : [ { "href" : "xxx.de/uploads/profile_images/xxx.png",
            "rel" : "https://xxx.com/rels/image"
          },
          { "href" : "http://xxx.de/api/users/xxx/profile",
            "rel" : "self"
          }
        ],
      "name" : "Foo Bar",
      "status" : "Status",
      "timezone" : "CET"
    },
  "slug" : "foobaar",
  "username" : "foobaar"
}

Accessing Method:

public static User parseUser(String json) {
        JSONObject jsonObject;
        Gson gson = new Gson();

        try {
            jsonObject = new JSONObject(json);
            Log.v(TAG,jsonObject.toString(2));
            User u = gson.fromJson(jsonObject.toString(), User.class);
            return u;

        } catch (JSONException e){
            Log.e(TAG, "There was an error parsing the JSON (USER)" + e);
        }
        return null;
    }

Where is my mistake? And can i use a HashMap like this with GSON? Thanks in advance

Use a Gson Deserializer class. they are pretty straightforward:

To make this work, you have to make sure the parser isn't going to try and serialize the infringing object (in this case your Map). I would rename your map object to _links or somesuch so the serializer will skip over it. Do the same thing as this example for your Profile as well.

Once you've done that you have to deserialize it and make sure to include the deserializer in the gson object:

    User u;
    GsonBuilder gb = new GsonBuilder();
    gb.registerTypeAdapter(User.class, new UserDeserializer());
    Gson g = gb.create();
    u = g.fromJson(json, User.class);


public class UserDeserializer  implements JsonDeserializer<UserDeserializer>
{
   @Override
   public User deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
    {
        User u = g.fromJson(json, User.class);
        JsonObject jo = (JsonObject)json;
        JsonElement je = jo.get("links");
        //iterate through the je element to fill your map.
    }

}