java json 序列化对象空值不处理_关于java:Jackson序列化:忽略空值(或null)

我当前正在使用杰克逊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;

}

}

}

这是我如何转换它:

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,但是它也不起作用! 感谢您的帮助!

如果该字段的值为null,如何告诉Jackson在序列化过程中忽略该字段,可能会重复吗?

您将注解放置在错误的位置-注解必须在类上,而不是在字段上。即:

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

真的没有办法使include.NON_NULL注释起作用吗?还是NON_EMTPY一个?因为我知道哪个将为空,但这取决于情况。我对要序列化/反序列化的每个对象使用相同的" JsonOperation"类,而Im仅根据情况初始化需要使用的变量。这是一个好方法吗,还是我应该做几个只包含我需要的变量的类(那样我就不必使用任何注释,因为永远不会有null / empty变量)

抱歉,我看到了现在的情况。看到我编辑的答案。

语法在最新版本中已更改为@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)和@JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY如果您需要非空和非空,请使用@JsonSerialize(include = JsonSerialize .Inclusion.NON_DEFAULT)

不工作!我都测试了。

在类之前或属性起作用之前使用@JsonSerialize(include = Inclusion.NON_NULL)...

我这样做了,序列化工作正常,但是我仍然在ADB中收到警告。任何想法如何删除那些?

2.x +使用JsonInlcude,下面使用JsonSerialize,请编辑您的答案。

@WestFarmer IIRC是正确的。如果您不同意,请自行编辑并查看是否获得批准。欢迎来到SO :-)

@drewmoore,请再次检查,@JsonInclude(JsonSerialize.Inclusion.NON_NULL)应该是@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL),并且它也是旧的不赞成使用的方式。因此您应该写"在2.x以下版本中",而不是"在2.x +版本中"

2. +使用@JsonInclude(Include.NON_NULL)

我使用了@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL),但它似乎对我不起作用。是因为我正在使用@JsonProperty吗?我需要对bean成员使用@JsonProperty以指定JSON密钥。我究竟做错了什么?这是我的bean public class TransactionResponse { @JsonProperty("TRANS_STATUS") @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) private int transactionStatus; @JsonProperty("ORDER_ID") private long orderId; },我也尝试将@JsonSerialize放置在类之前,但在响应中,trans_status始终为0

您还可以设置全局选项:

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

您也可以尝试使用

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)

如果您要测试我测试过的版本低于2+(1.9.5)的杰克逊,则可以在类上方轻松使用此注释。不是为属性指定的,只是为类定义的。

不推荐使用JsonSerialize的include属性,而推荐使用JsonInclude

就像我说过的:杰克逊的版本低于2+(1.9.5)

问题询问特定的版本2.1.4

您需要添加导入com.fasterxml.jackson.annotation.JsonInclude;。

@JsonInclude(JsonInclude.Include.NON_NULL)

在POJO之上

如果您嵌套了POJO,那么

@JsonInclude(JsonInclude.Include.NON_NULL)

需要添加每个值。

注意:

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

使用旧的org.codehaus.jackson.annotate包时,是否有类似的功能?

是的,您可以在getter方法示例的顶部添加private int id; @JsonIgnore public int getId(){返回ID; }

与现有答案相同

对于杰克逊2.x

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

与现有答案相同

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

@JsonInclude(JsonInclude.Include.NON_NULL)

在字段级别或类级别使用以上注释均无法按预期方式工作。 POJO在我应用注释的地方是可变的。当我将POJO的行为更改为不可变时,注释发挥了神奇的作用。

我不确定该库的最新版本或先前版本是否具有类似行为,但是对于2.6.6,您肯定需要具有不可变POJO才能使注释起作用。

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

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

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

或者,您可以使用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

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

@JsonInclude(JsonInclude.Include.NON_ABSENT)

与现有答案相同


版权声明:本文为weixin_29538497原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。