代码之家  ›  专栏  ›  技术社区  ›  Shell_Leko

如何使用gson只返回一个特定的空字段?

  •  2
  • Shell_Leko  · 技术社区  · 7 年前

    如果我有一个简单的对象,如下所示:

    String name;
    String email;
    int age;
    boolean isDeveloper;
    

    那么让我们假设接收到的JSON对象具有以下值:

    {"name":null,"email":null,"age":26,"isDeveloper":true}
    

    当使用gson作为默认值反序列化此json时,我有:

    {"age":26,"isDeveloper":true}
    

    但是电子邮件字段丢失会导致我的应用程序随后出现故障,因此我想添加

    email = null;
    

    序列化回JSON,并且只有该字段值为空。也不忽略任何非空字段。

    其他空值不应添加到生成的JSON中。

    我尝试使用默认的gson生成器反序列化,然后使用允许空值的gson序列化,如下所示:

    Gson gson = new GsonBuilder().serializeNulls().create();
    

    问题是:这将查找对象类中的所有空/空值,并将它们全部设置。

    “name”:空,“email”:空,“age”:26,“isdeveloper”:真
    

    如何设置email属性空值,然后将其序列化回仅包含此字段的JSON,而不忽略任何其他非空值?

    我用的是GSON 2.2.4版

    以下是示例代码:

    import com.google.gson.Gson;
    import com.google.gson.GsonBuilder;
    
    public class App
    {
        private class UserSimple {
            public String name;
            public String email;
            public int age;
            public boolean isDeveloper;
    
    
            UserSimple(String name, String email, int age, boolean isDeveloper) {
                this.name = name;
                this.email = email;
                this.age = age;
                this.isDeveloper = isDeveloper;
            }
    
        }
    
        public static void main( String[] args )
        {
            String userJson = "{'age':26,'email':'abc@dfg.gh','isDeveloper':true,'name':null}";
            Gson gson = new GsonBuilder()
                    .setPrettyPrinting()
                    .disableHtmlEscaping()
                    .create();
    
    
            Gson gsonBuilder = new GsonBuilder().serializeNulls().create();
    
            UserSimple deserializedObj = gson.fromJson(userJson, UserSimple.class);
            System.out.println("\n"+gson.toJson(deserializedObj));
            deserializedObj.email = null;
    
    
            String serializedObj = gsonBuilder.toJson(deserializedObj, UserSimple.class);
            System.out.println("\n"+serializedObj);
    
    
        }
    }
    
    2 回复  |  直到 7 年前
        1
  •  4
  •   mnj11    7 年前

    class MyCustomTypeAdapter extends TypeAdapter<UserSimple> {
        @Override
        public void write(JsonWriter writer, UserSimple userSimple) throws IOException {
            writer.beginObject();
            if(userSimple.getName() != null){
                writer.name("name");
                writer.value(userSimple.getName());
            }
    
            // you want to include email even if it's null
            writer.name("email");
            writer.value(userSimple.getEmail());
    
            if(userSimple.getAge() != null){
                writer.name("age");
                writer.value(userSimple.getAge());
            }
            if(userSimple.getDeveloper() != null){
                writer.name("isDeveloper");
                writer.value(userSimple.getDeveloper());
            }
            writer.endObject();
        }
    
        public UserSimple read(JsonReader reader) throws IOException {
        // you could create your own
            return null;
        }
    } 
    

    String userJson = "{'age':null,'email':null,'isDeveloper':true,'name':'somename'}";
    

    serializedObj :{"name":"somename","email":null,"isDeveloper":true}
    

    String userJson = "{'age':20,'email':null,'isDeveloper':true,'name':'somename'}";
    

    serializedObj :{"name":"somename","email":null,"age":20,"isDeveloper":true}
    

    https://google.github.io/gson/apidocs/com/google/gson/TypeAdapter.html

        2
  •  1
  •   Coder-Man    7 年前

    import com.fasterxml.jackson.annotation.JsonInclude;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.ObjectWriter;
    
    public class Main {
        static class Person {
            @JsonInclude(JsonInclude.Include.ALWAYS)
            private String name;
            @JsonInclude(JsonInclude.Include.NON_NULL)
            private String email;
            @JsonInclude(JsonInclude.Include.NON_NULL)
            private Integer age;
            public Person(String name, String email, Integer age) {
                this.name = name;
                this.email = email;
                this.age = age;
            }
    
            public String getName() {
                return name;
            }
    
            public String getEmail() {
                return email;
            }
    
            public Integer getAge() {
                return age;
            }
        }
        public static void main(String[] args) throws Exception {
            ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); // pretty printing only enabled for demonstration purposes
            String test = ow.writeValueAsString(new Person(null, null, 2));
            System.out.println(test);
        }
    }
    

    {
      "name" : null,
      "age" : 2
    }
    

    name JsonInclude.Include.ALWAYS

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.6</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.9.6</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.6</version>
    </dependency>
    

    Gson serialize null for specific class or field