使用Gson进行自定义反序列化

时间:2015-04-09 23:31:09

标签: java gson

我一直在努力改进我的代码,但不知道怎么回事,我得到的是这样的:

{   
"name": "Jhon",
"lastName": "Smith",
"clothes": {
    "gender":"male",
    "Shirt": {
        "id": 113608,
        "name": "Green Shirt",
        "size": "Large"
    },
    "Pants": {
        "id": 115801,
        "name": "Black Leather Pants",
        "size": "Large"
       }
    }
}

到目前为止它的工作方式是同时使用Shirt和Pants类,但因为它们是相同的,我试图只使用一个类来获得它们。我没有说明如何生成json所以必须使用它来了。

这是我的课程:

班级人员

public class Person{
    private String lastName;
    private String name;
    private Clothes clothes;
}

班级服装

public class Clothes{
    private Shirt Shirt;
    private Pants pants;
    private String gender;
}

班级衬衫

public class Shirt{
    private String id;
    private String name;
    private String size;
}

裤子和衬衫一样,问题是我不希望我的代码在他们决定添加另一件衣服的时候打破,所以我试图做这样的事情

班级服装

public class Clothes{
    private List<Something> clothList;
    private String gender;
}

1 个答案:

答案 0 :(得分:0)

不要使用2个单独的类(ShirtPants),而只需使用一个类 - 让我们说Cloth。试着这样做并且工作得很好:

人员类:

package com.dominikangerer.q29550820;

public class Person {
    private String name;
    private String lastName;
    private Clothes clothes;
}

衣服类:

package com.dominikangerer.q29550820;

public class Clothes {
    private String gender;
    private Cloth Shirt;
    private Cloth Pants;        
}

布类:

package com.dominikangerer.q29550820;

public class Cloth {
    private Integer id;
    private String name;
    private String size;
}

在构建这些类之后,我直接在一个小主类中尝试了它,这样就可以完美地反序列化。

Gson g = new Gson();
Person person = g.fromJson("{\"name\":\"Jhon\",\"lastName\":\"Smith\",\"clothes\":{\"gender\":\"male\",\"Shirt\":{\"id\":113608,\"name\":\"Green Shirt\",\"size\":\"Large\"},\"Pants\":{\"id\":115801,\"name\":\"Black Leather Pants\",\"size\":\"Large\"}}}", Person.class);

此处未使用@Expose@SerializedName("something"),因为不需要。

希望它可以帮助你 - 否则请更详细地解释你的问题,我会尽力帮助你。

-----------更新------------

通常,你可以很容易地投射一个Json,就像你在普通的Object中那样 - 但事情是在地图内部(clothes)你还有一个正常{ {1}}价值。为此,我建议您启用String功能Gson我会告诉您为什么以后这会是一个好主意。

让我们开始吧: 我删除了@ExposeClothes Map<String, Object> Gson可以轻松反序列化 - 这里的问题是我们在该地图中也有性别。我修改了Person类,它现在的工作原理如下:

人v2:

package com.dominikangerer.q29550820;

public class Person {
    private String name;

    private String lastName;

    @SerializedName("clothes")
    private Map<String, Object> clothesWrapper;

    public String getGender() {
        return clothesWrapper.get("gender").toString();
    }

    public void setGender(String gender) {
        this.clothesWrapper.put("gender", gender);
    }
}

现在我们已经可以将gender映射为String并使用getter和setter对其进行修改 - 仍然有包含Object s的地图。接下来我们不想要Map<String, Object> - 反序列化和序列化它完全没问题 - 但是对于Cloth本身 - 它很愚蠢所以让#&# 39;用最简单的方法摆脱它:

我们修改我们的Person类:

人物v3:

package com.dominikangerer.q29550820;

public class Person {
    @Expose
    private String name;

    @Expose
    private String lastName;

    @Expose
    @SerializedName("clothes")
    private Map<String, Object> clothesWrapper;

    private Map<String, Cloth> clothes;

    public String getGender() {
        return clothesWrapper.get("gender").toString();
    }

    public void setGender(String gender) {
        this.clothesWrapper.put("gender", gender);
    }

    public Map<String, Cloth> getClothes() {
        if (clothes == null) {
            Gson g = new Gson();
            clothes = new HashMap<String, Cloth>();
            for (Entry<String, Object> entry : clothesWrapper.entrySet()) {
                if (entry.getKey().equals("gender")) {
                    continue;
                }
                String helper = g.toJson(entry.getValue());
                Cloth cloth = g.fromJson(helper, Cloth.class);
                clothes.put(entry.getKey(), cloth);
            }
        }
        return clothes;
    }
}

正如您所看到的,我们现在间接地投射了所有Cloth es - 我们必须这样做,因为这是将所有LinkedTreeMap转换为{{1}的最简单方法}} - Cloth没有遇到Object。正如您所看到的,我们现在有一个ClassCastException让Gson解析对象(找不到更好的名字 - 抱歉)和没有Expose的Map<String,Object> clothesWrapper地图。现在,您还需要使用enableExpose选项设置Gson,其工作方式如下:

(在这里使用Person v3 Class - 只需调试它 - 就像魅力一样)

Map<String, Cloth> clothes

您可以在此github repository

中找到所有课程