Fastjson
这玩意儿不多说,Alibaba出品,出过几次重大的安全漏洞,然而仍然很风行。这里写一下它怎么解决枚举。
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --><dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.76</version></dependency>
序列化为name()值
默认就是,啥也不必动
import com.alibaba.fastjson.JSON;enum Gender { BOY, GIRL, UNKNOW}class User { private Integer id; private Gender gender; public User() { } public User(Integer id, Gender gender) { super(); this.id = id; this.gender = gender; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Gender getGender() { return gender; } public void setGender(Gender gender) { this.gender = gender; }}public class MainTest { public static void main(String[] args) throws Exception { // 序列化为JSON输入 User user = new User(1, Gender.BOY); String jsonString = JSON.toJSONString(user); System.out.println(jsonString); // {"gender":"BOY","id":1} // 反序列化为对象 user = JSON.parseObject(jsonString, User.class); System.out.println(user.getGender()); // BOY }}
序列化为ordinal()值
全局设置
代码跟下面没有变动,就须要在结尾增加一句代码,任何枚举,都会被序列化为ordinal()值
JSON.DEFAULT_GENERATE_FEATURE &= ~SerializerFeature.WriteEnumUsingName.mask;
// 全局设置,枚举的序列化应用 ordinal() JSON.DEFAULT_GENERATE_FEATURE &= ~SerializerFeature.WriteEnumUsingName.mask; // 序列化为JSON输入,枚举值为 ordinal() User user = new User(1, Gender.BOY); String jsonString = JSON.toJSONString(user); System.out.println(jsonString); // {"gender":0,"id":1} // 反序列化为对象 user = JSON.parseObject(jsonString, User.class); System.out.println(user.getGender()); // BOY
非凡设置
只想针对某一次序列化失效。只须要调用JSON.toJSONString
的重载办法,增加配置就行。
public static String toJSONString(Object object, int defaultFeatures, SerializerFeature... features)
// 序列化为JSON输入,本次把枚举值序列化为 ordinal() User user = new User(1, Gender.BOY); String jsonString = JSON.toJSONString(user, JSON.DEFAULT_GENERATE_FEATURE & ~SerializerFeature.WriteEnumUsingName.mask); System.out.println(jsonString); // {"gender":0,"id":1} // 反序列化为对象 user = JSON.parseObject(jsonString, User.class); System.out.println(user.getGender()); // BOY
序列化为自定义属性
很多人也喜爱给枚举定义一个公有的属性,序列化为JSON时,心愿以这个属性值作为value,这个时候就须要本人定义JSON的序列化和反序列化实现了。Fastjson提供了2个接口。用户管制序列化和反序列化行为,这个切实是太简略,这里不多说。看代码
- ObjectSerializer
- ObjectDeserializer
序列化器的定义
import java.io.IOException;import java.lang.reflect.Type;import com.alibaba.fastjson.serializer.JSONSerializer;import com.alibaba.fastjson.serializer.ObjectSerializer;public class GenderEnumSerializer implements ObjectSerializer { @Override public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { // 强制把值转换为Gender Gender gender = (Gender) object; // 序列化为自定义的name属性,输入就行 serializer.out.writeString(gender.getName()); }}
反序列化器的定义
import java.lang.reflect.Type;import com.alibaba.fastjson.parser.DefaultJSONParser;import com.alibaba.fastjson.parser.JSONToken;import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;public class GenderEnumDeserializer implements ObjectDeserializer { @SuppressWarnings("unchecked") @Override public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { // 解析值为字符串 String value = parser.parseObject(String.class); // 遍历所有的枚举实例 for (Gender gender : Gender.values()) { if (gender.getName().equals(value)) { // 胜利匹配,返回实例 return (T) gender; } } // 没有匹配到,能够抛出异样或者返回null return null; } @Override public int getFastMatchToken() { // 仅仅匹配字符串类型的值 return JSONToken.LITERAL_STRING; }}
对象 & 枚举的定义
enum Gender { BOY("男"), GIRL("女"), UNKNOW("不晓得"); public final String name; Gender(String name) { this.name = name; } public String getName() { return name; }}class User { private Integer id; // 标识注解,指定枚举的序列化。反序列化实现类 @JSONField(serializeUsing = GenderEnumSerializer.class, deserializeUsing = GenderEnumDeserializer.class) private Gender gender; public User() { } public User(Integer id, Gender gender) { super(); this.id = id; this.gender = gender; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Gender getGender() { return gender; } public void setGender(Gender gender) { this.gender = gender; }}
测试
public class MainTest { public static void main(String[] args) throws Exception { // 序列化为JSON输入,枚举值为 getName() User user = new User(1, Gender.UNKNOW); String jsonString = JSON.toJSONString(user); System.out.println(jsonString); // {"gender":"不晓得","id":1} // 反序列化为对象 user = JSON.parseObject(jsonString, User.class); System.out.println(user.getGender()); // UNKNOW }}
最初
很显然,自定义 ObjectSerializer /ObjectDeserializer 的形式最为灵便,能够思考形象一个接口进去,让所有的枚举都实现接口。这样针对接口编写ObjectSerializer /ObjectDeserializer实现,就能够很好的复用了。
本文首发:https://springboot.io/t/topic...