杰克逊序列化:忽略空值(或null)

时间:2013-04-18 17:37:30

标签: java json jackson

我目前正在使用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 个答案:

答案 0 :(得分:218)

你有一个错误的注释 - 它需要在课堂上,而不是在场上。即:

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

答案 1 :(得分:44)

您还可以设置全局选项:

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

答案 2 :(得分:15)

您也可以尝试使用

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)

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

答案 3 :(得分:12)

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

添加

@JsonInclude(JsonInclude.Include.NON_NULL)

在POJO之上

如果您已嵌套POJO,那么

@JsonInclude(JsonInclude.Include.NON_NULL)

需要添加每个值。

注意: JAXRS(Jersey)自动处理2.6及以上的场景。

答案 4 :(得分:3)

对于jackson 2.x

在场之前的

@JsonInclude(JsonInclude.Include.NON_NULL)。

答案 5 :(得分: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));
    }
}

输出:

{"isLoggedIn":false}

我使用 gson-2.2.4

答案 6 :(得分: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序列化时忽略所有空字段,则在类级别使用注释,但如果您只想在类中忽略几个字段,则在这些特定字段上使用它。这种方式更具可读性和可读性。如果您想改变特定响应的行为,则易于维护。

答案 7 :(得分:0)

如果你想从序列化中排除布尔类型,

下面的代码可能会有所帮助:

        TouchAction ta = new TouchAction(driver);
        ta.longPress(x,y).moveTo(x,y).release().perform();
相关问题