在编写代码的时候,对于DTO/POJO类,我们有时候希望某些字段不被JSON序列化,可以在字段上使用 @JsonIgnore 注解。FastJSON2兼容Jackson的部分注解,例如对于 @JsonIgnore, FastJSON2 同样支持,在序列化的时候不会输出相应的字段。但是,如果我们希望在FastJSON的时候输出相关字段,但是Jackson序列话的时候不输出某些字段,可以用下面的方法来兼容。
FastJSON2的实现方法
FastJSON2 POM依赖:
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.52</version>
</dependency>
但是,如果你希望Jackson忽略某些字段,但是用FastJSON输出的时候,不想忽略这个字段,可以使用
JSONFactory.setUseJacksonAnnotation(false);
使用该方法有一个条件,就是必须在程序启动之后,第一次使用JSON.toJSONString之前,立刻调用这个语句,如果你在程序运行当中,再来设置和切换这个功能,是不会生效的。
这是因为FastJSON2 内部会缓存序列化类的元数据(BeanInfo 等),之后再调用 JSONFactory.setUseJacksonAnnotation(false) 是无效的,因为缓存已经生成,不再重新解析。
如果希望动态生效,则可以在调用这个代码之后,清理缓存重新设置注解行为。
完整代码如下:
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class User {
private String username;
@JsonIgnore
private String password;
private int age;
}
测试代码:
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Main {
public static void main(String[] args) throws Exception {
User user = new User("testUser", "secret123", 25);
System.out.println("Original User Object: " + user);
String fastjsonStr = JSON.toJSONString(user);
System.out.println("\nFastJSON Serialization:");
System.out.println(fastjsonStr);
JSONFactory.setUseJacksonAnnotation(false);
JSONFactory.getDefaultObjectWriterProvider().cleanup(User.class);
fastjsonStr = JSON.toJSONString(user);
System.out.println("\nFastJSON Serialization2:");
System.out.println(fastjsonStr);
ObjectMapper jacksonMapper = new ObjectMapper();
String jacksonStr = jacksonMapper.writeValueAsString(user);
System.out.println("\nJackson Serialization:");
System.out.println(jacksonStr);
}
}
运行效果:
FastJSON Serialization:
{"age":25,"username":"testUser"}
FastJSON Serialization2:
{"age":25,"password":"secret123","username":"testUser"}
Jackson Serialization:
{"username":"testUser","age":25}
FastJSON的实现方法
POM依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.10</version>
</dependency>
在FastJSON中,如果要实现类似的效果,可以考虑采用不同的字段名称来实现,注意一定不要用 getXXX开头,否则Jackson也会序列化输出XXX新字段名:
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class User {
private String username;
@JsonIgnore
private String password;
private int age;
@JSONField(name = "password", serialize = true)
public String passwordForFastJSON() {
return password;
}
}
使用代码:
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Main {
public static void main(String[] args) throws Exception {
User user = new User("testUser", "secret123", 25);
System.out.println("Original User Object: " + user);
String fastjsonStr = JSON.toJSONString(user);
System.out.println("\nFastJSON Serialization:");
System.out.println(fastjsonStr);
ObjectMapper jacksonMapper = new ObjectMapper();
String jacksonStr = jacksonMapper.writeValueAsString(user);
System.out.println("\nJackson Serialization:");
System.out.println(jacksonStr);
}
}
运行结果:
Original User Object: User(username=testUser, password=secret123, age=25)
FastJSON Serialization:
{"age":25,"password":"secret123","username":"testUser"}
Jackson Serialization:
{"username":"testUser","age":25}