如何让Jackson序列化枚举时使用枚举名称
问题描述
使用Jackson 2.14.2序列化WebSocketMsg对象时,其中的MsgType枚举当前被序列化为枚举值(如heartbeat或数字1),希望改为序列化枚举的名称(如HEARTBEAT)。已尝试给枚举添加@JsonFormat(shape = JsonFormat.Shape.OBJECT)但无效,相关代码如下:
序列化代码
WebSocketMsg resp = new WebSocketMsg(MsgType.USER_CHAT, responseMsg); ObjectMapper objectMapper = new ObjectMapper(); String resultJson = objectMapper.writeValueAsString(resp);
枚举定义
@Schema(implementation = MsgType.class) @JsonFormat(shape = JsonFormat.Shape.OBJECT) public enum MsgType { HEARTBEAT(1, "heartbeat"); private final int code; private final String desc; MsgType(int code, String desc) { this.code = code; this.desc = desc; } }
WebSocketMsg类定义
@Data @NoArgsConstructor @AllArgsConstructor public class WebSocketMsg { private MsgType msgType; private String msg; }
期望JSON格式
{ "msgType": "HEARTBEAT", "msg": "balabala....." }
解决方案
首先移除枚举上的@JsonFormat(shape = JsonFormat.Shape.OBJECT)——这个注解的作用是把枚举序列化为包含所有属性的对象(而非单一字符串),和你想要的效果完全相反。之后可以通过以下两种方式实现需求:
方式一:给枚举添加@JsonValue注解
在MsgType枚举中添加一个标注了@JsonValue的方法,指定返回枚举的名称:
@Schema(implementation = MsgType.class) public enum MsgType { HEARTBEAT(1, "heartbeat"); private final int code; private final String desc; MsgType(int code, String desc) { this.code = code; this.desc = desc; } // 标注@JsonValue,指定序列化时返回枚举名称 @JsonValue public String getEnumName() { return this.name(); } // 原有getter方法可保留 public int getCode() { return code; } public String getDesc() { return desc; } }
方式二:全局配置ObjectMapper
如果希望所有枚举都统一序列化为名称,可以在创建ObjectMapper时配置全局规则:
WebSocketMsg resp = new WebSocketMsg(MsgType.HEARTBEAT, "balabala....."); ObjectMapper objectMapper = new ObjectMapper(); // 开启枚举使用名称序列化 objectMapper.enable(SerializationFeature.WRITE_ENUMS_USING_NAME); // 确保关闭toString序列化(默认已关闭,可省略) objectMapper.disable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING); String resultJson = objectMapper.writeValueAsString(resp);
两种方式都能生成你期望的JSON格式。
内容的提问来源于stack exchange,提问作者Dolphin
相关产品推荐
相关产品推荐

