จะบอกแจ็คสันให้เพิกเฉยฟิลด์ในระหว่างการทำให้เป็นอนุกรมได้อย่างไรถ้าค่าเป็นโมฆะ?


687

แจ็กสันสามารถกำหนดค่าให้ละเว้นค่าฟิลด์ในระหว่างการทำให้เป็นอนุกรมได้อย่างไรถ้าค่าของฟิลด์นั้นเป็นโมฆะ

ตัวอย่างเช่น:

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

คำตอบ:


1102

ในการระงับคุณสมบัติซีเรียลไลซ์เซชั่นด้วยค่า Null โดยใช้ Jackson> 2.0 คุณสามารถกำหนดค่าObjectMapperโดยตรงหรือใช้ประโยชน์จาก@JsonIncludeหมายเหตุประกอบ:

mapper.setSerializationInclusion(Include.NON_NULL);

หรือ:

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

หรือคุณสามารถใช้@JsonIncludeใน getter เพื่อให้แอททริบิวปรากฏขึ้นหากค่าไม่เป็นโมฆะ

เป็นตัวอย่างที่สมบูรณ์มากขึ้นมีอยู่ในคำตอบของฉันที่จะวิธีการป้องกันค่า null ภายในแผนที่และสาขา null ภายในถั่วจากการต่อเนื่องผ่านแจ็คสัน


81
สำหรับโครงการของฉันสิ่งนี้ได้ผล: @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL); ยังไม่มีคำอธิบายประกอบของคุณ
Emmanuel Touzery

13
API เปลี่ยนไปเล็กน้อยเมื่อใช้รุ่น 2.0
โปรแกรมเมอร์ Bruce

11
@ProgrammerBruce -1 เปลี่ยนคำตอบของคุณตามเนื่องจากคุณทราบถึงการเปลี่ยนแปลง
Martin Asenov

19
ใช่ฉันเพิ่งยืนยันว่า@JsonIncludeสัญกรณ์ใช้งานไม่ได้ แต่มันใช้งานได้อย่างมีเสน่ห์: @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) (ฉันใช้ Jackson 1.9.12 กับ Spring 3.2.2)
gstroup

17
@MartinAsenov - คำตอบแสดง API ล่าสุด มันก็เปลี่ยนไปจากไวยากรณ์@JsonSerialize @JsonIncludeไวยากรณ์ที่เก่ากว่าเลิกใช้แล้ว
รถกระบะโลแกน

128

ด้วย Jackson> 1.9.11 และ <2.x ใช้@JsonSerializeคำอธิบายประกอบเพื่อทำสิ่งนี้:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)


10
ทุกวันนี้ (Jackson 2.x) เป็นวิธีการนี้เลิกใช้แล้ว
rustyx

39
@JsonInclude (JsonInclude.Include.NON_NULL)
ZiglioUK

3
@JsonSerialize(using = FooSerializer.class, include = JsonSerialize.Inclusion.NON_NULL)ไม่ทำงาน ค่า nullable ถูกทำให้เป็นอนุกรม
herau

1
มันเลิกใช้แล้ว แต่ถ้าคุณต้องการที่จะดูแลสิ่งเก่า ๆ คำตอบนี้ใช้ได้ทั้งหมด! ขอบคุณ @WTK :)
DominikAngerer

อย่างที่ทราบแจ็คสัน 1.9.12 นั้นเป็นมาตรฐานใน WebSphere 8.5 หวังว่าข้อมูลนี้จะช่วยให้คนอื่นประหยัดเวลาได้มาก :-)
bakoyaro

122

เพียงเพื่อขยายคำตอบอื่น ๆ - หากคุณต้องการควบคุมการละเว้นค่า Null บนพื้นฐานต่อฟิลด์ให้ใส่คำอธิบายประกอบในคำถาม (หรือเพิ่มคำอธิบายประกอบของ 'getter')

ตัวอย่าง -ที่นี่เท่านั้นfieldOneจะถูก ommitted จาก json ถ้ามันเป็นโมฆะ fieldTwoจะรวมอยู่เสมอไม่ว่าจะเป็นโมฆะหรือไม่ก็ตาม

public class Foo {

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

    private String fieldTwo;
}

ในการละเว้นค่า Null ทั้งหมดในคลาสเป็นค่าเริ่มต้นให้ใส่คำอธิบายประกอบคลาส คำอธิบายประกอบแบบต่อฟิลด์ / ทะเยอทะยานยังสามารถใช้เพื่อแทนที่ค่าเริ่มต้นนี้หากจำเป็น

ตัวอย่าง -ที่นี่fieldOneและfieldTwoจะถูก ommitted จาก json หากพวกเขาเป็นโมฆะตามลำดับเพราะนี่คือชุดเริ่มต้นโดยคำอธิบายประกอบในชั้นเรียน fieldThreeอย่างไรก็ตามจะแทนที่ค่าเริ่มต้นและจะรวมอยู่ด้วยเสมอเนื่องจากมีคำอธิบายประกอบในฟิลด์

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

    private String fieldOne;

    private String fieldTwo;

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

UPDATE

ข้างต้นเป็นสำหรับแจ็คสัน 2 สำหรับแจ็คสันรุ่นก่อนหน้าคุณต้องใช้:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) 

แทน

@JsonInclude(JsonInclude.Include.NON_NULL)

หากการอัปเดตนี้มีประโยชน์โปรด upvote คำตอบของ ZiglioUK ด้านล่างมันชี้ให้เห็นคำอธิบายประกอบ Jackson 2 ที่ใหม่กว่าก่อนที่ฉันจะอัปเดตคำตอบเพื่อใช้!


ไม่ควรใส่คำอธิบายประกอบลงบนฟิลด์เพื่อลบล้าง?
Abhinav Vishak

@AbhinavVishak คุณถูกต้อง - ขอบคุณ! มันเป็นตัวพิมพ์ดีดคัดลอกเมื่อฉันอัปเดตคำตอบเพื่อใช้ Jackson 2 แก้ไข
davnicwil

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) เลิกใช้แล้ว
Yar

1
@ ใช่ใช่นั่นเลิกใช้แล้วใน Jackson 2.x ฉันได้กล่าวว่าคุณจำเป็นต้องใช้งานเฉพาะในรุ่นก่อนหน้าของแจ็คสันซึ่งไม่เพียง แต่จะไม่คัดค้านมันเป็นตัวเลือกเท่านั้น
davnicwil

60

ใน Jackson 2.x ให้ใช้:

@JsonInclude(JsonInclude.Include.NON_NULL)

นี่คือสิ่งที่จะถูกวางไว้บนสนาม
am

1
@ams, คำอธิบายประกอบนี้ควรห่อคลาส
Edgard Leal

คุณสามารถรวมชื่อที่มีคุณสมบัติครบถ้วนได้ด้วยหรือไม่ แจ็คสันมีคำอธิบายประกอบหลายรายการที่มีชื่อเดียวกันและแพคเกจที่แตกต่างกันดังนั้นจึงไม่ชัดเจน
วินซ์

คุณกำลังพูดว่ามีคำอธิบายประกอบ @JsonInclude หลายรายการในแจ็คสัน ฉันไม่มีความคิดเห็น. ชื่อที่ผ่านการรับรองควรเป็นอย่างไร?
อย่า

ความสับสนเกี่ยวกับชื่อมักเกิดจาก Jackson 1.x และ 2.x โดยใช้แพ็คเกจ Java ที่แตกต่างกันสำหรับทุกสิ่งเพื่อหลีกเลี่ยงข้อขัดแย้งตัวโหลดคลาส (wrt รุ่นคลาสที่เข้ากันไม่ได้) เนื่องจากคำตอบนี้สำหรับ 2.x แพคเกจสำหรับคำอธิบายประกอบจะเป็นcom.fasterxml.jackson.annotation- แจ็คสัน 1.x มีorg.codehaus.jackson.annoation
StaxMan

39

คุณสามารถใช้การกำหนดค่า mapper ต่อไปนี้:

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

ตั้งแต่ 2.5 คุณสามารถใช้:

mapper.setSerializationInclusion(Include.NON_NULL);

3
เนื่องจากสิ่งนี้เลิกใช้แล้วใน 1.9 ใช้ mapper.getSerializationConfig (). withSerializationInclusion (JsonSerialize.Inclusion.NON_NULL);
Asa

7
.. หรือโดยตรง: mapper.setSerializationInclusion (NON_NULL);
Asa

@ruslan: อาจเป็นเพราะเอกสารของgetSerializationConfig() says: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

สำหรับการใช้ 2.5.4mapper.setSerializationInclusion(Include.NON_NULL);
อาร์ตูโรโวลเป


12

ในกรณีของฉัน

@JsonInclude(Include.NON_EMPTY)

ทำให้มันทำงาน


2
NON_EMPTY จะแตกต่างกันอย่างละเอียดจาก NON_NULL - มันจะไม่สนใจค่า null ว่าเป็นความจริง แต่จะยังไม่สนใจค่าถือว่าว่างเปล่าซึ่งอาจจะไม่พฤติกรรมที่ต้องการ ดูjavadocsแจ็กสันสำหรับข้อมูลเพิ่มเติม
davnicwil

ฉันชอบคำตอบนี้เพราะการกลับมาเป็นตัวเลือกจากสิ่งที่เป็นตัวเลือกจริง ๆ เป็นความคิดที่ดีและด้วย NON_NULL คุณจะได้รับบางสิ่งที่ไม่{ }เป็นโมฆะ เดียวกันกับ AtomicReference - ผู้บริโภคไม่สนใจว่าผู้พัฒนาเลือกที่จะบังคับใช้ความปลอดภัยของเธรดในการแสดงการตอบสนองภายในหรือไม่
Lucas Ross

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

ควรทำงาน.

Include.NON_EMPTYบ่งชี้ว่าคุณสมบัตินั้นเป็นอนุกรมหากค่าไม่เป็นโมฆะและไม่ว่างเปล่า Include.NON_NULLบ่งชี้ว่าคุณสมบัตินั้นเป็นอนุกรมหากค่าไม่เป็นโมฆะ


2
JsonInclude.Include.NON_EMPTY- เพียงพอแล้วเนื่องจากครอบคลุมกรณี NOT_NULL
Ilya Buziuk

5

หากคุณต้องการเพิ่มกฎนี้ให้กับทุกรุ่นใน Jackson 2.6+ ให้ใช้:

mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

5

หากในSpring Bootคุณสามารถปรับแต่งแจ็คสันObjectMapperได้โดยตรงผ่านไฟล์คุณสมบัติ

ตัวอย่างapplication.yml:

spring:
  jackson:
    default-property-inclusion: non_null # only include props if non-null

ค่าที่เป็นไปได้คือ:

always|non_null|non_absent|non_default|non_empty

เพิ่มเติม: https://docs.spring.io/spring-boot/docs/current/reference/html/howto-spring-mvc.html#howto-customize-the-jackson-objectmapper


5

สิ่งนี้จะทำงานในSpring boot 2.0.3+ และ Jackson 2.0+

import com.fasterxml.jackson.annotation.JsonInclude;

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

1
ที่@JsonInclude(JsonInclude.Include.NON_NULL)ทำงานให้ฉันในSpring boot 2.1.2และคำอธิบายประกอบของ Jackson 2.9.0
manasouza

@manasouza ใช่พวกเขายังคงความสอดคล้องกับการปรับปรุงทั้งหมด
Deva


2

สิ่งนี้ทำให้ฉันหนักใจมาระยะหนึ่งและในที่สุดก็พบปัญหา ปัญหานี้เกิดจากการนำเข้าผิด ก่อนหน้านี้ฉันเคยใช้

com.fasterxml.jackson.databind.annotation.JsonSerialize

ซึ่งเลิกใช้แล้ว เพียงแทนที่การนำเข้าโดย

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

และใช้มันเป็น

@JsonSerialize(include=Inclusion.NON_NULL)

2

การกำหนดค่าส่วนกลางหากคุณใช้ 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;
    }

}

การตั้งค่า serializationInclusion ไม่ได้เพิ่มเข้าไปอีก public Jackson2ObjectMapperBuilder serializationInclusion(JsonInclude.Include serializationInclusion) { this.serializationInclusion = serializationInclusion; return this; }; เราควรใช้รัศมีการแจงนับที่มากขึ้น เช่น NON_ABSENT รวมถึง NON_NULL และ NON_EMPTY รวมถึงทั้งสอง ดังนั้นควรเป็นbuilder.serializationInclusion(JsonInclude.Include.NON_EMPTY); JacksonInclude doc เท่านั้น
Olgun Kaya

2

หากคุณพยายามเรียงลำดับรายการวัตถุและหนึ่งในนั้นเป็นโมฆะคุณจะต้องจบลงด้วยการรวมรายการว่างไว้ใน JSON ด้วย

mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

จะส่งผลให้:

[{myObject},null]

เพื่อรับสิ่งนี้:

[{myObject}]

เราสามารถทำสิ่งที่ชอบ:

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

เคล็ดลับ: หากคุณใช้ DropWizard คุณสามารถดึงข้อมูลที่ObjectMapperJersey ใช้มาใช้environment.getObjectMapper()


1

เรามีคำตอบสำหรับคำถามนี้มากมาย คำตอบนี้อาจเป็นประโยชน์ในบางสถานการณ์หากคุณต้องการละเว้นค่า Null คุณสามารถใช้ NOT_NULL ในระดับชั้นเรียนได้ ดังต่อไปนี้

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

บางครั้งคุณอาจต้องละเว้นค่าว่างเช่นคุณอาจเริ่มต้น arrayList แต่ไม่มีองค์ประกอบในรายการนั้นในเวลานั้นใช้หมายเหตุประกอบแบบ NOT_EMPTY เพื่อละเว้นฟิลด์ค่าว่างเหล่านั้น

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

0

ใช้แจ็คสัน 2.x +

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

.withSerializationInclusion(JsonInclude.Include.NON_NULL)ใช่ไหม
herau

ขอบคุณที่ชี้ให้เห็นว่าฉันจะระงับการอัปเกรด :-(
ZiglioUK

@ruslan: อาจเป็นเพราะเอกสารของgetSerializationConfig()says: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

นอกจากนี้คุณต้องเปลี่ยนวิธีการของคุณเมื่อใช้ Map myVariable ตามที่อธิบายไว้ในเอกสารประกอบเพื่อเผยแพร่ nulls:

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

กรณีที่หนึ่ง

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

กรณีที่สอง

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

หากsomeStringเป็นโมฆะมันจะถูกละเว้นในทั้งสองกรณี ถ้าsomeStringเป็น "" มันจะถูกละเว้นเฉพาะในกรณีที่สอง

เหมือนกันสำหรับList = nullหรือList.size() = 0

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.