175

I'm currently using jackson 2.1.4 and I'm having some trouble ignoring fields when I'm converting an object to a JSON string.

Here's my class which acts as the object to be converted:

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

And here's how I convert it:

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

Here's the output:

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

How can I avoid those null values? I only want to take required information for the "subscription" purpose!

Here's exactly the output that I'm looking for:

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

I also tried @JsonInclude(Include.NON_NULL) and put all my variables to null, but it didn't work either! Thanks for your help guys!

moffeltje
  • 4,521
  • 4
  • 33
  • 57
Shinnyx
  • 2,144
  • 2
  • 14
  • 21
  • Possible duplicate of [How to tell Jackson to ignore a field during serialization if its value is null?](https://stackoverflow.com/questions/11757487/how-to-tell-jackson-to-ignore-a-field-during-serialization-if-its-value-is-null) – moffeltje Jul 25 '18 at 12:02

8 Answers8

301

You have the annotation in the wrong place - it needs to be on the class, not the field. i.e:

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

As noted in comments, in versions below 2.x the syntax for this annotation is:

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

The other option is to configure the ObjectMapper directly, simply by calling mapper.setSerializationInclusion(Include.NON_NULL);

(for the record, I think the popularity of this answer is an indication that this annotation should be applicable on a field-by-field basis, @fasterxml)

drew moore
  • 31,565
  • 17
  • 75
  • 112
  • There's really no way to make the include.NON_NULL annotation to work? Or the NON_EMTPY one? Because I know which one will be null, but it depends on the situation. I'm using the same "JsonOperation" class for every object that I want to serialize / deserialize and I'm only initializing the variables that I need to use depending on the situation. Is this a good way to do it or I should do severals classes containing only the variables that I need (that way I wouldn't have to use any annotation, since there will never be a null/empty variable) – Shinnyx Apr 18 '13 at 17:53
  • 31
    The syntax has changed in most recent version to @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) and @JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY If you need both non-null and non-empty, use @JsonSerialize(include = JsonSerialize.Inclusion.NON_DEFAULT) – Maciej Aug 29 '13 at 20:32
  • 1
    Use @JsonSerialize(include=Inclusion.NON_NULL) before class or before property it worked... – sawan Oct 29 '14 at 10:43
  • I did this and the serialization works properly, but I still get warnings in ADB. Any ideas how to remove those? – deepwinter Jul 17 '15 at 22:16
  • 2.x + use JsonInlcude, below use JsonSerialize, please edit your answer. – WestFarmer Aug 10 '16 at 03:57
  • @WestFarmer IIRC it's correct as is. If you disagree, edit it yourself and see if it gets approved. Welcome to SO :-) – drew moore Aug 10 '16 at 04:12
  • 3
    @drewmoore please check again, `@JsonInclude(JsonSerialize.Inclusion.NON_NULL) `should be `@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)` and also it's the old deprecated way. so you should wrote "in version below 2.x", not "in version 2.x+" – WestFarmer Aug 10 '16 at 06:49
  • 4
    2.+ use `@JsonInclude(Include.NON_NULL)` – Honghe.Wu Oct 03 '16 at 14:16
  • I used `@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)` but it does not seem to work for me. Is it because I am using `@JsonProperty` ? I need to use `@JsonProperty` for the bean members to specify the JSON key. What am I doing wrong? This is my bean `public class TransactionResponse { @JsonProperty("TRANS_STATUS") @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) private int transactionStatus; @JsonProperty("ORDER_ID") private long orderId; }` I hv also tried placing the `@JsonSerialize` before the class but still the trans_status always is 0 in response – Akshay Kasar Apr 19 '17 at 12:08
  • @AkshayKasar 0 is not the same as null. Judging from the Jackson documentation, `@JsonInclude(JsonInclude.Include.NON_DEFAULT)` should work in your case. – Frans Sep 28 '20 at 11:42
  • 1
    if you want it in a field use @JsonInclude(JsonInclude.Include.NON_NULL) – thedrs Mar 13 '22 at 12:52
60

You can also set the global option:

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
nomad
  • 847
  • 7
  • 10
19

Also you can try to use

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)

if you are dealing with jackson with version below 2+ (1.9.5) i tested it, you can easily use this annotation above the class. Not for specified for the attributes, just for class decleration.

erhanasikoglu
  • 1,685
  • 1
  • 21
  • 33
18

You need to add import com.fasterxml.jackson.annotation.JsonInclude;

Add

@JsonInclude(JsonInclude.Include.NON_NULL)

on top of POJO

If you have nested POJO then

@JsonInclude(JsonInclude.Include.NON_NULL)

need to add on every values.

NOTE: JAXRS (Jersey) automatically handle this scenario 2.6 and above.

Koray Tugay
  • 22,894
  • 45
  • 188
  • 319
vaquar khan
  • 10,864
  • 5
  • 72
  • 96
6

For jackson 2.x

@JsonInclude(JsonInclude.Include.NON_NULL)

just before the field.

Koray Tugay
  • 22,894
  • 45
  • 188
  • 319
Gere
  • 2,114
  • 24
  • 24
4

I was having similar problem recently with version 2.6.6.

@JsonInclude(JsonInclude.Include.NON_NULL)

Using above annotation either on filed or class level was not working as expected. The POJO was mutable where I was applying the annotation. When I changed the behaviour of the POJO to be immutable the annotation worked its magic.

I am not sure if its down to new version or previous versions of this lib had similar behaviour but for 2.6.6 certainly you need to have Immutable POJO for the annotation to work.

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

Above option mentioned in various answers of setting serialisation inclusion in ObjectMapper directly at global level works as well but, I prefer controlling it at class or filed level.

So if you wanted all the null fields to be ignored while JSON serialisation then use the annotation at class level but if you want only few fields to ignored in a class then use it over those specific fields. This way its more readable & easy for maintenance if you wanted to change behaviour for specific response.

Amrut
  • 971
  • 1
  • 9
  • 17
1

Or you can use GSON [https://code.google.com/p/google-gson/], where these null fields will be automatically removed.

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}

I used gson-2.2.4

buræquete
  • 14,226
  • 4
  • 44
  • 89
anij
  • 1,322
  • 5
  • 23
  • 39
1

Code bellow may help if you want to exclude boolean type from serialization either:

@JsonInclude(JsonInclude.Include.NON_ABSENT)
Ivan Aracki
  • 4,861
  • 11
  • 59
  • 73
Alexander
  • 47
  • 1
  • 2
  • 7