Làm thế nào để bảo Jackson bỏ qua một trường trong quá trình tuần tự hóa nếu giá trị của nó là null?


687

Làm thế nào Jackson có thể được cấu hình để bỏ qua một giá trị trường trong quá trình tuần tự hóa nếu giá trị của trường đó là null.

Ví dụ:

public class SomeClass {
   // what jackson annotation causes jackson to skip over this value if it is null but will 
   // serialize it otherwise 
   private String someValue; 
}

Câu trả lời:


1102

Để loại bỏ các thuộc tính tuần tự hóa với các giá trị null bằng Jackson> 2.0, bạn có thể định cấu hình ObjectMappertrực tiếp hoặc sử dụng @JsonIncludechú thích:

mapper.setSerializationInclusion(Include.NON_NULL);

hoặc là:

@JsonInclude(Include.NON_NULL)
class Foo
{
  String bar;
}

Ngoài ra, bạn có thể sử dụng @JsonIncludetrong một getter để thuộc tính sẽ được hiển thị nếu giá trị không phải là null.

Một ví dụ đầy đủ hơn có sẵn trong câu trả lời của tôi về Cách ngăn các giá trị null bên trong Bản đồ và các trường null bên trong một bean không được tuần tự hóa thông qua Jackson .


81
cho dự án của tôi, điều này đã làm việc : @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL); bằng cách nào đó chú thích của bạn không có sẵn
Emmanuel Touzery

13
API đã thay đổi một chút với bản phát hành 2.0.
Lập trình viên Bruce

10
@ProgrammerBruce -1 thay đổi câu trả lời của bạn cho phù hợp vì bạn biết về sự thay đổi.
Martin Asenov

19
Vâng, tôi vừa xác nhận rằng @JsonIncludeký hiệu không hoạt động, nhưng điều này hoạt động như một cơ duyên: @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) (Tôi đang sử dụng Jackson 1.9.12 với Mùa xuân 3.2.2.)
gstroup

17
@MartinAsenov - câu trả lời cho thấy API gần đây nhất; nó đã được thay đổi từ @JsonSerializecú pháp thành @JsonInclude. Cú pháp cũ không được dùng nữa.
Pickup Logan

128

Với Jackson> 1.9.11 và <2.x, hãy sử dụng @JsonSerializechú thích để làm điều đó:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)


10
Ngày nay (Jackson 2.x) là cách tiếp cận này không được chấp nhận.
rustyx

39
@JsonInclude (JsonInclude.Include.NON_NULL)
ZiglioUK

3
@JsonSerialize(using = FooSerializer.class, include = JsonSerialize.Inclusion.NON_NULL)không hoạt động. giá trị nullable được tuần tự hóa.
herau

1
Điều đó không được chấp nhận nhưng nếu bạn cần duy trì những thứ cũ thì câu trả lời này hoàn toàn tốt! cảm ơn @WTK :)
DominikAngerer

Một lưu ý phụ, Jackson 1.9.12 là tiêu chuẩn trong WebSphere 8.5, hy vọng thông tin này sẽ giúp người khác tiết kiệm được nhiều thời gian để tôi tìm ra điều này :-)
bakoyaro

122

Chỉ để mở rộng các câu trả lời khác - nếu bạn cần kiểm soát việc bỏ qua các giá trị null trên cơ sở từng trường, hãy chú thích trường đang đề cập (hoặc thay vào đó là chú thích 'getter' của trường).

ví dụ - ở đây fieldOnesẽ chỉ được thông báo từ json nếu nó là null. fieldTwosẽ luôn được bao gồm bất kể nó là null.

public class Foo {

    @JsonInclude(JsonInclude.Include.NON_NULL) 
    private String fieldOne;

    private String fieldTwo;
}

Để bỏ qua tất cả các giá trị null trong lớp làm mặc định, chú thích lớp. Chú thích trên mỗi trường / getter vẫn có thể được sử dụng để ghi đè mặc định này nếu cần.

ví dụ - ở đây fieldOnefieldTwosẽ được thông báo từ json nếu chúng là null, vì đây là mặc định được đặt bởi chú thích lớp. fieldThreetuy nhiên sẽ ghi đè mặc định và sẽ luôn được đưa vào, vì chú thích trên trường.

@JsonInclude(JsonInclude.Include.NON_NULL)
public class Foo {

    private String fieldOne;

    private String fieldTwo;

    @JsonInclude(JsonInclude.Include.ALWAYS)
    private String fieldThree;
}

CẬP NHẬT

Trên đây là cho Jackson 2 . Đối với các phiên bản trước của Jackson, bạn cần sử dụng:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) 

thay vì

@JsonInclude(JsonInclude.Include.NON_NULL)

Nếu bản cập nhật này hữu ích, vui lòng nâng cấp câu trả lời của ZiglioUK bên dưới, nó chỉ ra chú thích Jackson 2 mới hơn trước khi tôi cập nhật câu trả lời của mình để sử dụng nó!


Không nên chú thích trên trường LUÔN LUÔN để ghi đè?
Abhinav Vishak

@AbhinavVishak bạn nói đúng - cảm ơn! Đó là một lỗi đánh máy sao chép khi tôi cập nhật câu trả lời để sử dụng Jackson 2. Đã chỉnh sửa.
davnicwil

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) không được chấp nhận
Yar

1
@ Có, điều đó không được chấp nhận ở Jackson 2.x. Tôi đã tuyên bố rằng bạn chỉ cần sử dụng nó trong các phiên bản trước của Jackson, nơi không chỉ không bị phản đối, đó là lựa chọn duy nhất.
davnicwil

60

Trong Jackson 2.x, sử dụng:

@JsonInclude(JsonInclude.Include.NON_NULL)

cái này được đặt trên sân
AMS

1
@ams, chú thích này sẽ bao bọc một lớp
Edgard Leal

Bạn cũng có thể bao gồm tên đủ điều kiện? Jackson có nhiều chú thích có cùng tên và một gói khác nhau, vì vậy điều đó không rõ ràng.
Vince

bạn đang nói có nhiều chú thích @JsonInclude ở Jackson phải không? Tôi không ý kiến. Tên đủ điều kiện nên là gì sau đó? vui lòng chỉnh sửa câu trả lời
ZiglioUK

Nhầm lẫn với tên rất có thể là do Jackson 1.x và 2.x sử dụng các gói Java khác nhau cho mọi thứ, để tránh xung đột trình tải lớp (phiên bản lớp không tương thích wrt). Vì câu trả lời này là cho 2.x, gói cho các chú thích sẽ là com.fasterxml.jackson.annotation- Jackson 1.x đã cóorg.codehaus.jackson.annoation
StaxMan

39

Bạn có thể sử dụng cấu hình mapper sau:

mapper.getSerializationConfig().setSerializationInclusion(Inclusion.NON_NULL);

Kể từ 2.5 bạn có thể sử dụng:

mapper.setSerializationInclusion(Include.NON_NULL);

3
Vì điều này không được chấp nhận trong 1.9, hãy sử dụng mapper.getSerializationConfig (). WithSerializationIninating (JsonSerialize.Ininating.NON_NULL);
Asa

7
.. hoặc trực tiếp: mapper.setSerializationIninating (NON_NULL);
Asa

@ruslan: Có lẽ vì tài liệu getSerializationConfig() nói:Note that since instances are immutable, you can NOT change settings by accessing an instance and calling methods: this will simply create new instance of config object.
Zero3

Để sử dụng 2.5.4mapper.setSerializationInclusion(Include.NON_NULL);
Arturo Volpe


12

trong trường hợp của tôi

@JsonInclude(Include.NON_EMPTY)

làm cho nó hoạt động.


2
NON_EMPTY khác biệt tinh tế với NON_NULL - nó sẽ bỏ qua các giá trị null, điều đó đúng, nhưng cũng sẽ bỏ qua các giá trị được coi là trống, có thể không phải là hành vi mong muốn. Xem Jackson javadocs để biết thêm thông tin
davnicwil

Tôi thích câu trả lời này bởi vì trả về Tùy chọn từ những thứ thực sự là tùy chọn là một ý tưởng hay và chỉ với NON_NULL, bạn sẽ nhận được một cái gì đó giống như { }null, chuyển thành ngữ Java một cách vô nghĩa cho người tiêu dùng. tương tự với AtomicReference - người tiêu dùng không quan tâm đến cách nhà phát triển chọn thực thi an toàn luồng trên biểu diễn bên trong của phản hồi.
Lucas Ross

8
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonInclude(JsonInclude.Include.NON_EMPTY)

nên làm việc.

Include.NON_EMPTYchỉ ra rằng thuộc tính được tuần tự hóa nếu giá trị của nó không rỗng và không trống. Include.NON_NULLchỉ ra rằng thuộc tính được tuần tự hóa nếu giá trị của nó không phải là null.


2
JsonInclude.Include.NON_EMPTY- là đủ vì nó bao gồm trường hợp KHÔNG_NULL
Ilya Buziuk

5

Nếu bạn muốn thêm quy tắc này cho tất cả các mô hình trong Jackson 2.6+, hãy sử dụng:

mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);


5

Điều này sẽ hoạt động trong Spring boot 2.0.3+ và Jackson 2.0+

import com.fasterxml.jackson.annotation.JsonInclude;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class ApiDTO
{
    // your class variable and 
    // methods
}

1
Điều đó cũng @JsonInclude(JsonInclude.Include.NON_NULL)làm việc với tôi trên Spring boot 2.1.2Jackson chú thích 2.9.0
manasouza

@manasouza Có, họ đã duy trì tính nhất quán cho tất cả các cập nhật.
Deva


2

Điều này đã gây rắc rối cho tôi trong một thời gian và cuối cùng tôi đã tìm thấy vấn đề. Vấn đề là do nhập sai. Trước đó tôi đã sử dụng

com.fasterxml.jackson.databind.annotation.JsonSerialize

Mà đã bị phản đối. Chỉ cần thay thế nhập khẩu bằng

import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;

và sử dụng nó như

@JsonSerialize(include=Inclusion.NON_NULL)

2

Cấu hình toàn cầu nếu bạn sử dụng Spring

@Configuration
public class JsonConfigurations {

    @Bean
    public Jackson2ObjectMapperBuilder objectMapperBuilder() {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.serializationInclusion(JsonInclude.Include.NON_NULL);
        builder.serializationInclusion(JsonInclude.Include.NON_EMPTY);
        builder.failOnUnknownProperties(false);
        return builder;
    }

}

Đặt serializationIninating không thêm cái này vào cái khác. public Jackson2ObjectMapperBuilder serializationInclusion(JsonInclude.Include serializationInclusion) { this.serializationInclusion = serializationInclusion; return this; }; Người ta nên sử dụng bán kính lớn hơn của liệt kê bao gồm. ví dụ: NON_ABSENT bao gồm NON_NULL và NON_EMPTY bao gồm cả hai. Do đó, nó chỉ nên là builder.serializationInclusion(JsonInclude.Include.NON_EMPTY); JacksonInclude doc
Olgun Kaya

2

Nếu bạn đang cố gắng tuần tự hóa một danh sách các đối tượng và một trong số chúng là null, bạn sẽ kết thúc bao gồm cả mục null trong JSON ngay cả với

mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

sẽ cho kết quả:

[{myObject},null]

để có được điều này:

[{myObject}]

người ta có thể làm một cái gì đó như:

mapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
        @Override
        public void serialize(Object obj, JsonGenerator jsonGen, SerializerProvider unused)
                throws IOException
        {
            //IGNORES NULL VALUES!
        }
    });

MIPO: Nếu bạn đang sử dụng DropWizard, bạn có thể truy xuất việc ObjectMapperđang được Jersey sử dụng bằng cách sử dụngenvironment.getObjectMapper()


1

Chúng tôi có rất nhiều câu trả lời cho câu hỏi này. Câu trả lời này có thể hữu ích trong một số trường hợp Nếu bạn muốn bỏ qua các giá trị null, bạn có thể sử dụng NOT_NULL ở cấp lớp. như sau

@JsonInclude(Include.NON_NULL)
class Foo
{
  String bar;
}

Đôi khi bạn có thể cần bỏ qua các giá trị trống, chẳng hạn như bạn có thể đã khởi tạo mảng ListList nhưng không có phần tử nào trong danh sách đó. Trong thời gian đó, sử dụng chú thích NOT_EMPTY để bỏ qua các trường giá trị trống đó

@JsonInclude(Include.NON_EMPTY)
class Foo
{
  String bar;
}

0

Jackson 2.x + sử dụng

mapper.getSerializationConfig().withSerializationInclusion(JsonInclude.Include.NON_NULL);

.withSerializationInclusion(JsonInclude.Include.NON_NULL)thay vì phải không?
herau

Cảm ơn bạn đã chỉ ra điều đó, tôi sẽ không nâng cấp :-(
ZiglioUK

@ruslan: Có lẽ vì tài liệu getSerializationConfig()nói:Note that since instances are immutable, you can NOT change settings by accessing an instance and calling methods: this will simply create new instance of config object.
Zero3

0

Ngoài ra, bạn phải thay đổi cách tiếp cận của mình khi sử dụng Map myVariable như được mô tả trong tài liệu để làm nổi bật null:

From documentation:
com.fasterxml.jackson.annotation.JsonInclude

@JacksonAnnotation
@Target(value={ANNOTATION_TYPE, FIELD, METHOD, PARAMETER, TYPE})
@Retention(value=RUNTIME)
Annotation used to indicate when value of the annotated property (when used for a field, method or constructor parameter), or all properties of the annotated class, is to be serialized. Without annotation property values are always included, but by using this annotation one can specify simple exclusion rules to reduce amount of properties to write out.

*Note that the main inclusion criteria (one annotated with value) is checked on Java object level, for the annotated type, and NOT on JSON output -- so even with Include.NON_NULL it is possible that JSON null values are output, if object reference in question is not `null`. An example is java.util.concurrent.atomic.AtomicReference instance constructed to reference null value: such a value would be serialized as JSON null, and not filtered out.

To base inclusion on value of contained value(s), you will typically also need to specify content() annotation; for example, specifying only value as Include.NON_EMPTY for a {link java.util.Map} would exclude Maps with no values, but would include Maps with `null` values. To exclude Map with only `null` value, you would use both annotations like so:
public class Bean {
   @JsonInclude(value=Include.NON_EMPTY, content=Include.NON_NULL)
   public Map<String,String> entries;
}

Similarly you could Maps that only contain "empty" elements, or "non-default" values (see Include.NON_EMPTY and Include.NON_DEFAULT for more details).
In addition to `Map`s, `content` concept is also supported for referential types (like java.util.concurrent.atomic.AtomicReference). Note that `content` is NOT currently (as of Jackson 2.9) supported for arrays or java.util.Collections, but supported may be added in future versions.
Since:
2.0

0

Trường hợp một

@JsonInclude(JsonInclude.Include.NON_NULL)
private String someString;

Trường hợp hai

@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String someString;

Nếu someStringlà null, nó sẽ bị bỏ qua trên cả hai trường hợp. Nếu someStringlà "" nó chỉ được bỏ qua trong trường hợp hai.

Tương tự cho List = nullhoặcList.size() = 0

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.