
Jackson 默认以枚举名称字符串形式序列化 enum;若误加 @JsonFormat(shape = JsonFormat.Shape.OBJECT),会导致转为 JSON 对象格式,只需移除该注解即可恢复名称序列化。
jackson 默认以枚举名称字符串形式序列化 enum;若误加 `@jsonformat(shape = jsonformat.shape.object)`,会导致转为 json 对象格式,只需移除该注解即可恢复名称序列化。
在使用 Jackson(如 jackson-databind:2.14.2)进行 JSON 序列化时,enum 类型的默认行为是直接输出其 name()(即大写标识符)作为字符串,例如 MsgType.HEARTBEAT 序列化为 "HEARTBEAT"。这恰好符合你期望的输出格式:
{
"msgType": "HEARTBEAT",
"msg": "balabala....."
}
但问题中的 MsgType 枚举被错误地标注了:
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum MsgType {
HEARTBEAT(1, "heartbeat");
// ...
}
⚠️ @JsonFormat(shape = JsonFormat.Shape.OBJECT) 的作用是将枚举序列化为一个 JSON 对象(需配合自定义序列化器或含字段的构造逻辑),而非字符串。即使枚举本身有参数(如 1 和 "heartbeat"),只要未显式注册 ToStringSerializer 或 EnumSerializer 的替代逻辑,Jackson 在 OBJECT 模式下会尝试将其视为 POJO —— 导致生成类似:
"msgType": {
"nr": 1,
"value": "heartbeat"
}
这显然偏离了你的目标。
✅ 正确做法非常简洁:完全移除 @JsonFormat(shape = JsonFormat.Shape.OBJECT)。保持枚举干净定义即可:
@Schema(implementation = MsgType.class) // OpenAPI 注解,不影响 Jackson 序列化
public enum MsgType {
HEARTBEAT(1, "heartbeat");
private final int nr;
private final String value;
MsgType(int nr, String value) {
this.nr = nr;
this.value = value;
}
// 可选:提供 getter,但非必须(仅用于反序列化或业务逻辑)
public int getNr() { return nr; }
public String getValue() { return value; }
}
此时,WebSocketMsg 类无需任何修改:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class WebSocketMsg {
private MsgType msgType;
private String msg;
}
完整测试验证:
@Test
void serializeEnumByName() throws JsonProcessingException {
WebSocketMsg resp = new WebSocketMsg(MsgType.HEARTBEAT, "balabala.....");
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(resp);
System.out.println(json);
// 输出:{"msgType":"HEARTBEAT","msg":"balabala....."}
}
? 补充说明:
- 若你确实需要按 value 字符串(如 "heartbeat")序列化,可使用 @JsonValue 标注对应 getter;
- 若需全局统一 enum 序列化策略(如全部用 name()),无需额外配置 —— 这就是 Jackson 2.12+ 的默认行为;
- @JsonFormat(shape = JsonFormat.Shape.STRING) 是显式声明“按 name 序列化”的安全写法(等价于默认),可选添加以增强可读性与意图表达;
- OpenAPI 的 @Schema 注解(来自 Springdoc 或 Swagger)仅影响 API 文档生成,不干预 Jackson 运行时序列化逻辑,可放心保留。
总结:删掉 @JsonFormat(shape = JsonFormat.Shape.OBJECT),Jackson 自动回归优雅简洁的枚举名称序列化 —— 简单、标准、零配置。










