Jackson - 浅析@JsonInclude

本文介绍@JsonInclude注解的使用方法,该注解用于控制JSON序列化过程中属性的包含规则,可应用于字段、方法或类级别,并提供多种排除规则。

@JsonInclude注解可用于指示何时可以对添加注解的属性进行序列化。通常会包含属性值,但是通过使用这个注解,我们可以基于属性值指定简单的排除规则。
这个注解可用于字段,方法或构造函数参数。它也可以在类上使用,这样对应的规则将应用于类的所有属性。
以下是@JsonInclude定义代码段:

@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD,
    ElementType.TYPE, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotation
public @interface JsonInclude
{
   public Include value() default Include.ALWAYS;//inclusion rules
   public Include content() default Include.ALWAYS;//rules on content (e.g. Map's elements)
   public Class<?> valueFilter() default Void.class;//used for values when Include.CUSTOM
   public Class<?> contentFilter() default Void.class;//used for contents values when Include.CUSTOM 
   
   public enum Include{
       ALWAYS,//always include property
       NON_NULL,//do not include property with null value
       NON_ABSENT,//no null values including no content null values like Optional, AtomicReference etc
       NON_EMPTY,//NON_NULL + NON_ABSENT + values like empty Collections/Map/arrays/String etc are excluded
       NON_DEFAULT,//no default values, e.g. no primitives with default values  
       CUSTOM,// a custom filter for exclusion specified by JsonInclude.valueFilter()
       USE_DEFAULTS//use defaults either from class level or ObjectMapper level
       ;
   }
}
例子
定义对象
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Employee {
 	private String name;
 	private String dept;
 	private String address;
}
Main方法
    public class ExampleMain {
        public static void main(String[] args) throws IOException {
            Employee employee = Employee.of("Trish", null, null);
            ObjectMapper om = new ObjectMapper();
            String jsonString = om.writeValueAsString(employee);
            System.out.println(jsonString);
        }
    }
结果
{"name":"Trish"}

如上所示,序列化期间不包含’dept’和’address’属性,因为我们为它们设置了null。

没有@JsonInclude

如果我们不使用@JsonIncludeEmployee类,那么输出将是:

{“ name”:“ Trish”,“ dept”:null,“ address”:null}
使用ObjectMapper#setDefaultPropertyInclusion()

此方法或ObjectMapper#setSerializationInclusion()可用于全局指定包含规则。例如,以下将产生与上面的示例相同的输出:

public class ExampleMain {
    public static void main(String[] args) throws IOException {
        Employee employee = Employee.of("Trish", null, null);
        ObjectMapper om = new ObjectMapper();
        om.setDefaultPropertyInclusion(JsonInclude.Include.NON_NULL);
        String jsonString = om.writeValueAsString(employee);
        System.out.println(jsonString);
    }
}
Jackson 的 `@JsonInclude` 注解用于在序列化过程中排除具有特定值的字段,例如 `null`、空字符串、空集合等。然而,在处理嵌套对象结构时,`@JsonInclude` 可能不会如预期那样生效,这通常与 Jackson 的默认行为以及嵌套对象的序列化方式有关。 在默认情况下,`@JsonInclude` 的作用范围仅限于当前类的字段,并不会自动递归应用到嵌套对象的内部字段。例如,如果一个字段是另一个 POJO 类型,那么该嵌套 POJO 的字段不会自动继承外层类的 `@JsonInclude` 策略,除非在嵌套类的字段或类级别上显式添加 `@JsonInclude` 注解。 此外,Jackson 的全局配置也会影响 `@JsonInclude` 的行为。如果未在 `ObjectMapper` 中启用相应的配置,即使在字段或类上设置了 `@JsonInclude`,也可能无法正确生效。例如,可以通过以下方式配置 `ObjectMapper` 以确保 `@JsonInclude` 对所有对象生效: ```java ObjectMapper mapper = new ObjectMapper(); mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); ``` 如果嵌套对象中存在默认构造函数缺失的问题,可能会导致反序列化失败或字段未被正确过滤,例如 `JsonMappingException: No suitable constructor found` 这类错误可能会影响字段的正常处理,从而间接影响 `@JsonInclude` 的行为[^3]。 为了确保 `@JsonInclude` 在嵌套结构中生效,建议采取以下措施: 1. 在嵌套对象的类或字段上单独添加 `@JsonInclude` 注解。 2. 确保 `ObjectMapper` 的全局配置与注解策略一致。 3. 检查嵌套对象的构造函数和字段访问权限,确保 Jackson 能够正确读写字段值。 ### 示例代码 ```java @JsonInclude(JsonInclude.Include.NON_NULL) public class OuterClass { private String outerField; private InnerClass inner; // getters and setters } public class InnerClass { private String innerField; // getters and setters } ``` 在上述代码中,若希望 `InnerClass` 中的 `innerField` 也遵循 `NON_NULL` 策略,则应在其类或字段上再次添加 `@JsonInclude` 注解。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值