⾃定义fastjson对枚举类型的序列化及反序列化过程通常,fastjson在序列化及反序列化枚举时,⼀般以下⼏种策略:
1).根据枚举的name值序列化及反序列化(默认)
2).根据枚举的ordinal序列化及反序列化
3).根据枚举的toString⽅法序列化,但是反序列仍采取默认的策略
这显然对我们的业务处理不够灵活,考虑以下⼀种情况:
有⼀个⽂章类,它有标题,内容等属性,其中有⼀个属性是枚举类,表⽰⽂章是否通过审核。
如下:
public class Article {private String title;
private String content;private AuditStatus status;public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
}public AuditStatus getStatus() {
return status;
}
public void setStatus(AuditStatus status) {
this.status = status;
}
}
对应的枚举类型,它包含⼀个标志状态的code:
public enum AuditStatus {
AUDITING(1), PASSED(2), FAILED(3);
private int code;
AuditStatus(int code){
}
public int getCode(){
return code;
}
public static AuditStatus convert(int code){
AuditStatus[] enums = AuditStatus.values();
for(AuditStatus e : enums){
de == code)
return e;
}
return null;
}
}
注意,上述的code并不等于枚举的ordinal。
我们希望AuditStatus序列化和反序列化的都是根据其code值来。
⽐如序列化成如下字符串:
{"content":"This is content","status":1,"title":"Article 1"}
并能正确反序列化得到的Article对象中的status属性是AuditStatus.AuditStatus。
我们逐个对应上述的策略来看看是否能满⾜我们的要求:
⽅法⼀:会将status序列化成AUDITING。因此不⾏
⽅法⼆:会将status根据ordinal来序列化,得到的结果为0,也不⾏。
⽅法三:我们可以override toString⽅法,这样可以是的序列化的结果正确,但是反序列化过程仍然不⾏。
那么没有其他⽅法可以满⾜我们的业务需求了嘛?
⽹上给出的⼀种⽅法如下,修改Article类:
1public class Article {
2
3private String title;
4
5private String content;
6
7private AuditStatus statusCode;
8
9public String getTitle() {
10return title;
11    }
12
13public void setTitle(String title) {
14this.title = title;
15    }
16
17public String getContent() {
18return content;
19    }
20
21public void setContent(String content) {
23    }
24
25    @JSONField(serialize = false)
26public AuditStatus getStatusCode() {
27return statusCode;
28    }
29
30    @JSONField(deserialize = true)
31public void setStatusCode(AuditStatus statusCode) {
32this.statusCode = statusCode;
33    }
34
35    @JSONField(name = "status")
36public int getStatus(){
Code();
38    }
39
40    @JSONField(name = "status")
41public AuditStatus setStatus(int code){
vert(code);
43    }
44 }
这种⽅式屏蔽了默认的序列化及反序列化过程:⾏7(将status重命名成statusCode),⾏25-33(禁⽌了statusCode的序列化);并增加了⾃定义的序列化过程(⾏35-43)。
我测试了这种⽅式,虽然能在序列化时得到正常结果,但是却⽆法正常发序列化。
测试代码:
public class SerializeTest {
public static void main(String[] args){
Article article = new Article();
article.setTitle("Article 1");
article.setContent("This is content");
article.setStatusCode(AuditStatus.AUDITING);
String str = JSONString(article);
System.out.println(str);
Article article1 = JSON.parseObject(str, Article.class);
System.out.StatusCode());
}
}
输出的结果:
因此这种做法并不可⾏,⽽且会让代码的可读性变差。
因此我推荐⼀种我尝试过成功的⽅法:编写⾃定义的编解码器,在通过@JsonField的serializeUsing和deserializeUsing属性指定编解码过程中使⽤的编解码器。
添加⾃定义的编解码器:
//ObjectSerializer和ObjectDeserializer分别是fastjson的编码器和解码器接⼝
public class AudtiStautsCodec implements ObjectSerializer, ObjectDeserializer {
//反序列化过程
public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
Object value = parser.parse();
return value == null ? null : (T) vert(TypeUtils.castToInt(value));
}
//暂时还不清楚
public int getFastMatchToken() {
return 0;
}
//序列化过程
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
serializer.write(((AuditStatus)object).getCode());
}
}
修改Article类,在status字段上增加@JsonField属性,并指定编解码器:
public class Article {
private String title;
private String content;
@JSONField(serializeUsing = AudtiStautsCodec.class, deserializeUsing = AudtiStautsCodec.class)
private AuditStatus status;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
}
public AuditStatus getStatus() {
return status;
}
public void setStatus(AuditStatus status) {
this.status = status;
}
}
在通过之前的测试代码测试⼀下结果是否正确:
public class SerializeTest {
public static void main(String[] args){
Article article = new Article();
article.setTitle("Article 1");
article.setContent("This is content");
article.setStatus(AuditStatus.AUDITING);
fastjson忽略属性
String str = JSONString(article);
System.out.println(str);
Article article1 = JSON.parseObject(str, Article.class);        System.out.Status());
}
}
结果如下:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。