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

我目前使用的是 jackson2.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,但它也不起作用!谢谢你们的帮助!

389148 次浏览

你把注释放错了地方——它需要放在课堂上,而不是字段上。例如:

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

还可以设置全局选项:

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

你也可以尝试使用

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)

如果你正在处理的 Jackson 版本低于2 + (1.9.5)我测试过,你可以很容易地使用这个注释上面的类。没有为属性指定,只是为类声明指定。

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

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

产出:

{"isLoggedIn":false}

我用的是 Gson-2.2.4

为了 Jackson 2. x

@JsonInclude(JsonInclude.Include.NON_NULL)

就在球场前面。

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

@JsonInclude(JsonInclude.Include.NON_NULL)

在 POJO 上面

如果您已经嵌套了 POJO,那么

@JsonInclude(JsonInclude.Include.NON_NULL)

需要增加每一个价值观。

注意: JAXRS (Jersey)自动处理这个场景2.6及以上版本。

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

@JsonInclude(JsonInclude.Include.NON_NULL)

在文件或类级别上使用上面的注释并没有像预期的那样起作用。在我应用注释的地方,POJO 是可变的。当我将 POJO 的行为更改为不可变时,注释发挥了神奇的作用。

我不确定这个库的新版本或以前的版本是否有类似的行为,但是对于2.6.6来说,当然需要有 Immutable POJO 来使注释工作。

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

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

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

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

@JsonInclude(JsonInclude.Include.NON_ABSENT)