java fastjson 枚举_java fastjson如何自定义转换含枚举类型对象(编程技巧)

在使用fastjson对Java对象进行序列化和反序列化时,如果含有枚举类型,默认会根据枚举变量的ordinal值进行反序列且序列化时显示枚举字面代表的字符串。经常这种行为不是我们想要的,那么如何进行定制化枚举类型的序列化和反序列? 举例如下

问题引出

假设待序列化和反序列化java对象结构如下

public class Msg {

private int id;

private StatusCodeEnum status;

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public StatusCodeEnum getStatus() {

return status;

}

public void setStatus(StatusCodeEnum status) {

this.status = status;

}

public static enum StatusCodeEnum {

OK(200, "正常"), SERVER_ERROR(500, "服务器错误");

private static final Map CODE_MAP = new HashMap();

static {

for (StatusCodeEnum typeEnum : StatusCodeEnum.values()) {

CODE_MAP.put(typeEnum.getCode(), typeEnum);

}

}

StatusCodeEnum(int code, String meaning) {

this.code = code;

this.meaning = meaning;

}

public int getCode() {

return code;

}

public String getMeaning() {

return meaning;

}

public static StatusCodeEnum getEnum(Integer code) {

return CODE_MAP.get(code);

}

private final int code;

private final String meaning;

}

}

对象内部定义了状态码枚举类StatusCodeEnum,包含两个实例OK、SERVER_ERROR。

反序列化问题

如何使用fastjson成功反序列如下json串?

{“id”:1,”status”:200}

显然,如果直接用Json.parseObject()方法进行反序列化,会报如下错误信息:

Exception in thread “main” com.alibaba.fastjson.JSONException: parse

enum com.netwaymedia.exhibition.nio.common.dto.Msg$StatusCodeEnum

error, value : 200 at

com.alibaba.fastjson.parser.deserializer.EnumDeserializer.deserialze(EnumDeserializer.java:48)

at

com.alibaba.fastjson.parser.deserializer.DefaultFieldDeserializer.parseField(DefaultFieldDeserializer.java:33)

原因分析:前面已经提过,fastjson默认使用ordinal值去查找对应的枚举实例,显示是获取不到的,所以抛出异常,需要修改status值为0才运行OK。

序列化问题

如果使用JSON.toJSONString()方法对上述Msg对象进行序列化,会得到如下json串

{“id”:1,”status”:”OK”}

显示不是我们所期待的原始字符串

{“id”:1,”status”:200}

如何解决上述两大问题?

优雅的解决方案

答案就在于fastjson提供注解JSONField。通过JSONField可灵活控制字段的序列化和反序列,重新修改Msg结构如下:

public class Msg {

private int id;

private StatusCodeEnum statusCode;

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

@JSONField(name = "status")

public int getStatus() {

return statusCode.getCode();

}

@JSONField(name = "status")

public void setStatus(int code) {

this.statusCode = StatusCodeEnum.getEnum(code);

}

@JSONField(serialize = false)

public StatusCodeEnum getStatusCode() {

return statusCode;

}

@JSONField(deserialize = false)

public void setStatusCode(StatusCodeEnum statusCode) {

this.statusCode = statusCode;

}

public static enum StatusCodeEnum {

OK(200, "正常"), BAD_REQUEST(400, "服务器出错");

private static final Map CODE_MAP = new HashMap();

static {

for (StatusCodeEnum typeEnum : StatusCodeEnum.values()) {

CODE_MAP.put(typeEnum.getCode(), typeEnum);

}

}

StatusCodeEnum(int code, String meaning) {

this.code = code;

this.meaning = meaning;

}

public int getCode() {

return code;

}

public String getMeaning() {

return meaning;

}

public static StatusCodeEnum getEnum(Integer code) {

return CODE_MAP.get(code);

}

private final int code;

private final String meaning;

}

}

思路是通过修改字段名为statusCode,并用JSONField注解该字段不进行序列和反序列化,但是提供getStatus/setStatus方法来定制化枚举变量statusCode的序列和反序列,完美的解决前面提到的两大问题。

这个方法我在网上还没看到过,是我自己尝试出来的,特别拿出来跟大家分享,不用谢,请叫我雷锋。 转自 http://blog.csdn.net/tang9140/article/details/51701099

你可能感兴趣的:(java,fastjson,枚举)