Java 反序列化映射<;字符串,对象>;带Gson的字段

Java 反序列化映射<;字符串,对象>;带Gson的字段,java,json,gson,Java,Json,Gson,我有一个具有此结构的用户对象: class User { private String id; private String name; private Map<String, Object> properties; // GETTERS & SETTERS } { "user": { "id:"123456789", "name:"azerty", "emailHash":"1234

我有一个具有此结构的用户对象:

class User {
    private String id;
    private String name;
    private Map<String, Object> properties;

    // GETTERS & SETTERS
}
{
    "user": {
        "id:"123456789",
        "name:"azerty",
        "emailHash":"123456789", // not used in User class
        "properties": {
            "p1":1,
            "p2":"test",
            "p3":[1, 2, 3, 4],
            "p4":{
               etc...
            }
        }
    }
}
属性的键是字符串,属性的值可以是字符串、整数、数组、布尔值、映射等

我尝试用Gson反序列化此JSON字符串,如下所示:

JsonParser parser = new JsonParser();
JsonElement element = parser.parse(jsonString);
JsonObject object = element.getAsJsonObject();

GsonBuilder builder = new GsonBuilder();
builder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
Gson gson = builder.create();
User user = (User) gson.fromJson(object.get("user"), new TypeToken<User>() {}.getType());
JsonParser=newjsonparser();
JsonElement元素=parser.parse(jsonString);
JsonObject object=element.getAsJsonObject();
GsonBuilder=新的GsonBuilder();
builder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_,带下划线);
Gson Gson=builder.create();
User User=(User)gson.fromJson(object.get(“User”),new-TypeToken(){}.getType());
字段“id”和“name”已正确插入,但字段“properties”保持为空

你知道我做错了什么吗? 提前感谢您的帮助

对我来说,这段代码:

public class Main {
    public static void main(String[] args) throws IOException {
    GsonBuilder builder = new GsonBuilder();
    builder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
    Gson gson = builder.create();
    FileInputStream inputStream = new FileInputStream(new File("bobi.json"));
    InputStreamReader reader = new InputStreamReader(inputStream);
    User user = gson.fromJson(reader, User.class);
    System.out.println(user.getName());
    System.out.println(user.getId());
    for (String property : user.getProperties().keySet()) {
        System.out.println("Key: " + property + " value: " + user.getProperties().get(property));
    }
    reader.close();
}
打印此文件:

azerty
123456789
Key: p1 value: 1.0
Key: p2 value: test
Key: p3 value: [1.0, 2.0, 3.0, 4.0]
Key: p4 value: {}
但是,请记住,我已经在解析的文件中剥离了包装json对象。该文件是:

{
        "id":"123456789",
        "name" : "azerty",
        "emailHash":"123456789", 
        "properties": {
            "p1":1,
            "p2":"test",
            "p3":[1, 2, 3, 4],
            "p4":{

            }
        }
}
此外,我还为
name
id
添加了结束双引号,这是您的示例中没有的

OP要求的
用户
类。出于打印的原因,我添加了getter和setter:

import java.util.Map;

class User {
    private String id;
    private String name;
    private Map<String, Object> properties;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Map<String, Object> getProperties() {
        return properties;
    }
    public void setProperties(Map<String, Object> properties) {
        this.properties = properties;
    }
}
import java.util.Map;
类用户{
私有字符串id;
私有字符串名称;
私人地图财产;
公共字符串getId(){
返回id;
}
公共无效集合id(字符串id){
this.id=id;
}
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
公共映射getProperties(){
归还财产;
}
公共void集合属性(映射属性){
这个。属性=属性;
}
}

我建议将属性设置为
JsonObject
,然后将JSON直接转换为
Map
。您的代码可以很好地工作,但有一个小问题:您似乎创建了一个名为
GsonBuilder
GsonBuilder
。如果这实际上是在编译,那么您之前创建了另一个
GsonBuilder
,并且错误地使用了它。除此之外。。。在我的机器上反序列化很好。
gsonBuilder
在我编写主题时出错。我在代码中使用的是
builder
。我将编辑我的主题以便更正。
properties
字段是否正确注入测试?对我来说,它保持为null是非常奇怪的…您是否尝试过:Gson Gson=new GsonBuilder().enableComplexMapKeySerialization().create();?在同样的情况下对我也有效。你能发布你使用的
user
对象吗?我尝试了你的代码,但是
属性
总是
。。。如果我能帮忙的话,我正在使用JDK7和Gson 2.2.2…@FranckYapadesouciAnso:补充道。Gson 2.1,java 1.7我发现了我的错误。问题出在田野调查政策上。谢谢你的帮助。祝你今天愉快@FranckYapadesouciAnso:它是如何影响解析的?事实上,这是我的错。对于主题,我简化了字段名。主题中的
属性
字段是我的代码中的
dynProp
。在带有下划线的
LOWER\u CASE\u上设置的字段命名策略尝试在json中搜索
dyn\u prop
,而不是
dynProp
。因此,我将命名策略切换到
IDENTITY
,现在它可以工作了!