158

我目前正在使用杰克逊 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,但它也不起作用!谢谢你们的帮助!

4

8 回答 8

279

您将注释放在错误的位置 - 它需要在类上,而不是在字段上。IE:

@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);

(作为记录,我认为这个答案的流行表明这个注释应该在逐个字段的基础上适用,@fasterxml)

于 2013-04-18T17:40:10.583 回答
55

您还可以设置全局选项:

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
于 2013-08-01T00:26:54.460 回答
16

你也可以尝试使用

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)

如果您正在处理版本低于 2+ (1.9.5) 的 jackson,我对其进行了测试,您可以轻松地在类上方使用此注释。不为属性指定,仅用于类声明。

于 2013-12-19T10:00:48.377 回答
14

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

添加

@JsonInclude(JsonInclude.Include.NON_NULL)

在 POJO 之上

如果你有嵌套 POJO 那么

@JsonInclude(JsonInclude.Include.NON_NULL)

需要添加每个值。

注意:JAXRS (Jersey) 自动处理此场景 2.6 及更高版本。

于 2015-09-15T08:20:48.177 回答
5

对于杰克逊 2.x

@JsonInclude(JsonInclude.Include.NON_NULL)

就在场前。

于 2014-11-12T21:58:29.927 回答
4

我最近在使用 2.6.6 版时遇到了类似的问题。

@JsonInclude(JsonInclude.Include.NON_NULL)

在归档或类级别上使用上述注释未按预期工作。POJO 在我应用注释的地方是可变的。当我将 POJO 的行为更改为不可变时,注释就发挥了它的魔力。

我不确定它的新版本或此库的先前版本是否具有类似的行为,但对于 2.6.6,您当然需要拥有不可变 POJO 才能使注释工作。

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

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

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

于 2016-08-19T11:18:56.537 回答
1

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

示例DTO.java

public class SampleDTO {

    String username;
    String email;
    String password;
    String birthday;
    String coinsPackage;
    String coins;
    String transactionId;
    boolean isLoggedIn;

    // getters/setters
}

测试.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));
    }
}

输出:

{"isLoggedIn":false}

我使用了 gson-2.2.4

于 2014-04-01T13:56:30.580 回答
0

如果您想从序列化中排除布尔类型,下面的代码可能会有所帮助:

@JsonInclude(JsonInclude.Include.NON_ABSENT)
于 2018-01-12T16:14:06.897 回答