Java中将枚举转化成Json对象,不使用@JsonFormat(shape = JsonFormat.Shape.OBJECT)

背景:

@JsonFormat(shape = JsonFormat.Shape.OBJECT)可以用作于枚举类,他可以返回一个对象json给前台,这个注解很方便,但是在我的项目中
用dubbo服务互相调用会存在反序列化失败的问题,虽然可以通过@JsonCreator注解去解决,但是这个方式对于所有的枚举来说都太过于一刀切了,其实还有另一种方式解决

需求:

我想要不改造枚举类从而实现和@JsonFormat(shape = JsonFormat.Shape.OBJECT)一样的效果。

实践:

1、首先我们需要将枚举继承一个公共接口,这个接口包含了自定义的方法,方便统一管理,我也推荐大家这样做,然后将枚举类继承该接口,重写方法

public interface EnumSetting {
	
	String getInnerCode();
	
	String getDesc();
}
public enum SystemStatusEnum implements EnumSetting {
	ENABLED(0, "启用"),DISABLED(1, "禁用");
	
	private  Integer code;
	private String desc;
	
	SystemStatusEnum(Integer code, String desc) {
		this.code = code;
		this.desc = desc;
	}
	
	public Integer getCode() {
		return code;
	}
	
	@Override
	public String getInnerCode() {
		return code.toString();
	}
	
	@Override
	public String getDesc() {
		return desc;
	}
	
	public static String getDescByCode(Integer code) {
		for (SystemStatusEnum c : SystemStatusEnum.values()) {
			if (c.getCode().equals(code)) {
				return c.getDesc();
			}
		}
		return null;
	}
	
	public static SystemStatusEnum getEnumByCode(Integer code) {
		for (SystemStatusEnum c : SystemStatusEnum.values()) {
			if (c.getCode().equals(code)) {
				return c;
			}
		}
		return null;
	}
	
	@Override
	public String toString() {
		return desc;
	}

2、编写一个枚举转化成Json的转化器,这个转化器可以定义你自己的字段,通过gen字段的write的各种方法可以实现丰富多样的数据格式。

public class EnumSettingsToJsonSerializer extends JsonSerializer<Enum> {
    @Override
    public void serialize(Enum value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if(ObjectUtils.isEmpty(value)){
            return;
        }
        gen.writeStartObject();
//        该转换类仅适用于Code定义为数字类型的枚举,否则会有bug,如果需要字符串类型的code请创建另一个
        gen.writeNumberField("code", Integer.parseInt(((EnumSetting) value).getInnerCode()));
        gen.writeStringField("desc", ((EnumSetting) value).getDesc());
        gen.writeStringField("innerCode", ((EnumSetting) value).getInnerCode());
        gen.writeStringField("value", ((EnumSetting) value).getDesc());
        gen.writeEndObject();
    }
}

3、准备一个实体类,实体类中包含了SystemStatusEnum枚举的字段(此处是我自己的枚举,你的项目请换成你自己的枚举),添加@JsonSerialize(using = EnumSettingsToJsonSerializer.class)的转化器

public class XXX{
  
  @JsonSerialize(using = EnumSettingsToJsonSerializer.class)
  private SystemStatusEnum enum;
}

验证:

"enum": {
  "code": 0,
  "desc": "启用",
  "innerCode": "0",
  "value": "启用"
}

返回结构是一个Json对象

总结:

这个方式可以满足我的需求,只需要在我想要转化的枚举字段中加上这个注解就可以了,这样枚举类不用加@Jsonformat注解,也不会有反序列化的问题了。当然,有很多解决方案,我只是其中一个,欢迎指正批评。

posted @ 2024-06-13 15:49  橙发  阅读(8)  评论(0编辑  收藏  举报