首页 文章

Jackson 序列化:忽略空值(或null)

提问于
浏览
111

我目前正在使用jackson 2.1.4,当我将对象转换为JSON字符串时,我在忽略字段时遇到了一些麻烦 .

这是我的类,它充当要转换的对象:

public class JsonOperation {

public static class Request {
    @JsonInclude(Include.NON_EMPTY)
    String requestType;
    Data data = new Data();

    public static class Data {
        @JsonInclude(Include.NON_EMPTY)
        String username;
        String email;
        String password;
        String birthday;
        String coinsPackage;
        String coins;
        String transactionId;
        boolean isLoggedIn;
    }
}

public static class Response {
    @JsonInclude(Include.NON_EMPTY)
    String requestType = null;
    Data data = new Data();

    public static class Data {
        @JsonInclude(Include.NON_EMPTY)
        enum ErrorCode { ERROR_INVALID_LOGIN, ERROR_USERNAME_ALREADY_TAKEN, ERROR_EMAIL_ALREADY_TAKEN };
        enum Status { ok, error };

        Status status;
        ErrorCode errorCode;
        String expiry;
        int coins;
        String email;
        String birthday;
        String pictureUrl;
        ArrayList <Performer> performer;
    }
}
}

以下是我如何转换它:

ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);

JsonOperation subscribe = new JsonOperation();

subscribe.request.requestType = "login";

subscribe.request.data.username = "Vincent";
subscribe.request.data.password = "test";


Writer strWriter = new StringWriter();
try {
    mapper.writeValue(strWriter, subscribe.request);
} catch (JsonGenerationException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (JsonMappingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

Log.d("JSON", strWriter.toString())

这是输出:

{"data":{"birthday":null,"coins":null,"coinsPackage":null,"email":null,"username":"Vincent","password":"test","transactionId":null,"isLoggedIn":false},"requestType":"login"}

我该如何避免这些空值?我只想获取“订阅”目的所需的信息!

这正是我正在寻找的输出:

{"data":{"username":"Vincent","password":"test"},"requestType":"login"}

我也尝试了@JsonInclude(Include.NON_NULL)并将我的所有变量都置为null,但它也没有用!谢谢你的帮助!

8 回答

  • 14

    你需要添加import com.fasterxml.jackson.annotation.JsonInclude;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    

    在POJO之上

    如果你已经嵌套了POJO

    @JsonInclude(JsonInclude.Include.NON_NULL)
    

    需要添加每个值 .

    注意:JAXRS(Jersey)自动处理此方案2.6及更高版本 .

  • -1

    对于 Jackson 2.x.

    @JsonInclude(JsonInclude.Include.NON_NULL)就在字段之前 .

  • 199

    你有一个错误的注释 - 它需要在类,而不是字段 . 即:

    @JsonInclude(Include.NON_NULL) //or Include.NON_EMPTY, if that fits your use case 
    public static class Request {
      // ...
    }
    

    如注释中所述,在版本2.x中,此批注的语法是:

    @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) // or JsonSerialize.Inclusion.NON_EMPTY
    

    另一个选项是直接配置 ObjectMapper ,只需调用 mapper.setSerializationInclusion(Include.NON_NULL);

    (为了记录,我认为这个答案的流行表明这个注释应该适用于逐场* ahem @fastxml *)

  • 40

    您还可以设置全局选项:

    objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    
  • 4

    您也可以尝试使用

    @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
    

    如果您正在使用低于2(1.9.5)的版本处理 Jackson ,我测试了它,您可以轻松地在课程上方使用此注释 . 不是为属性指定的,仅用于类去除 .

  • 2

    我最近在版本2.6.6中遇到了类似的问题 .

    @JsonInclude(JsonInclude.Include.NON_NULL)
    

    在字段或类级别上使用上述注释未按预期工作 . 在我应用注释的地方,POJO是可变的 . 当我将POJO的行为改为不可变时,注释发挥了作用 .

    我不确定它的新版本或此lib的以前版本是否具有类似的行为,但对于2.6.6,您肯定需要使用Immutable POJO才能使注释工作 .

    objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    

    在全局级别直接在ObjectMapper中设置序列化包含的各种答案中提到的上述选项也适用,但是,我更喜欢在类或文件级别控制它 .

    因此,如果您希望在JSON序列化时忽略所有空字段,则在类级别使用注释,但如果您只想在类中忽略几个字段,则在这些特定字段上使用它 . 这样,如果您想要更改特定响应的行为,它的可读性和易维护性 .

  • 2

    或者您可以使用GSON [https://code.google.com/p/google-gson/],其中将自动删除这些空字段 .

    SampleDTO.java

    public class SampleDTO {
    
        String username;
        String email;
        String password;
        String birthday;
        String coinsPackage;
        String coins;
        String transactionId;
        boolean isLoggedIn;
    
        // getters/setters
    }
    

    Test.java

    import com.google.gson.Gson;
    
    public class Test {
    
        public static void main(String[] args) {
            SampleDTO objSampleDTO = new SampleDTO();
            Gson objGson = new Gson();
            System.out.println(objGson.toJson(objSampleDTO));
        }
    }
    

    OUTPUT:

    {"isLoggedIn":false}
    

    我用 gson-2.2.4

  • 10

    如果要从序列化中排除布尔类型,则代码如下:

    @JsonInclude(JsonInclude.Include.NON_ABSENT)
    

相关问题