序列化问题记录:Jackson 与 Fastjson 的注解

前言

Java 后端开发中,我们经常需要处理 JSON 序列化和反序列化的问题。Spring 框架默认使用 Jackson 作为 JSON 处理库,但在某些情况下,我们也可能会使用 Fastjson 来处理特定的序列化需求。由于这两种库的注解不完全兼容,因此在同一个项目中同时使用它们时,可能会遇到一些问题。

问题

假设你有一个实体类 User,其中包含一些字段,并且你希望在某些情况下忽略某些字段,或者自定义序列化方式。你在字段上同时使用了 Jackson 或者 Fastjson 的注解,如下所示:

Jackson:
这种情况下,在 controller 层返回给前端,属性忽略注解(@JsonIgnore)和序列化方式注解(@JsonSerialize)是会生效的,但是使用 Fastjson 去序列化的时候就不生效!

import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import java.io.Serializable;

public class User implements Serializable {
    
    

    private Long id;

    @JsonIgnore
    private String password;

    @JsonSerialize(using = StringSerializer.class)
    private Date createdAt;

}

Fastjson:
这种情况下,在 Fastjson 序列化的时候可以正常处理字段属性忽略和序列方式,但是在 controller 层无效!

import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import java.io.Serializable;

public class User implements Serializable {
    
    

    private Long id;

    @JSONField(serialize = false, deserialize = false)
    private String password;

    @JSONField(format = "string")
    private Date createdAt;

}

解决方案

两种库的注解同时放置到属性字段上

import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import java.io.Serializable;

public class User implements Serializable {
    
    

    private Long id;

    @JsonIgnore
    @JSONField(serialize = false, deserialize = false)
    private String password;

    @JsonSerialize(using = StringSerializer.class)
    @JSONField(format = "string")
    private Date createdAt;

}

自定义复合注解

为了在同一个项目中同时支持 Jackson 和 Fastjson,并且避免重复编写相同的注解,我们可以创建自定义注解来实现通用性。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({
    
     ElementType.FIELD, ElementType.METHOD })
@com.fasterxml.jackson.annotation.JsonIgnore
@com.alibaba.fastjson.annotation.JSONField(serialize = false, deserialize = false)
public @interface IgnoreField {
    
    
}

@Retention(RetentionPolicy.RUNTIME)
@Target({
    
     ElementType.FIELD, ElementType.METHOD })
@com.fasterxml.jackson.databind.annotation.JsonSerialize(using = StringSerializer.class)
@com.alibaba.fastjson.annotation.JSONField(format = "string")
public @interface CustomStringSerializer {
    
    
}

序列化的时候使用统一的库

序列化的时候直接用ObjectMapper就行了,保持和 Spring 整合的 Jackson 统一就行了

猜你喜欢

转载自blog.csdn.net/qq_31762741/article/details/143145391