马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
枚举是Java中表达有限状态的利器。使用枚举不仅可以增强类型安全,同时也会极大提升代码的可读性和可维护性。
在 Spring MVC 项目中,当使用 Jackson 序列化枚举类型时,默认举动是序列化枚举的 name() 值(即枚举常量的名称)。但在实际开发中,我们通常需要更灵活的控制。以下是详细分析息争决方案:
1. Jackson 默认枚举序列化举动
- public enum EnterpriseAuthStatusEnum {
- PENDING, // 序列化为 "PENDING"
- APPROVED, // 序列化为 "APPROVED"
- REJECTED // 序列化为 "REJECTED"
- }
复制代码 当 EnterpriseAuthStatusVO 对象被序列化为 JSON 时:- {
- "enterpriseId": 12345,
- "kaiStatus": "PENDING" // 默认输出枚举的 name() 值
- }
复制代码 2. 常见需求与解决方案
需求 1:返回枚举的说明笔墨(而非常量名)
- @JsonFormat(shape = JsonFormat.Shape.OBJECT) // 关键注解
- public enum EnterpriseAuthStatusEnum {
- PENDING(0, "待审核"),
- APPROVED(1, "已通过"),
- REJECTED(2, "已拒绝");
-
- private final int code;
- private final String description;
-
- EnterpriseAuthStatusEnum(int code, String description) {
- this.code = code;
- this.description = description;
- }
-
- // 必须添加 getter
- public int getCode() {
- return code;
- }
-
- public String getDescription() {
- return description;
- }
- }
复制代码 序列化结果:- {
- "enterpriseId": 12345,
- "kaiStatus": {
- "code": 0,
- "description": "待审核"
- }
- }
复制代码 需求 2:返回自定义值(如 code)
- public enum EnterpriseAuthStatusEnum {
- PENDING(0),
- APPROVED(1),
- REJECTED(2);
-
- private final int code;
-
- EnterpriseAuthStatusEnum(int code) {
- this.code = code;
- }
-
- @JsonValue // 关键注解:标记作为序列化的值
- public int getCode() {
- return code;
- }
- }
复制代码 序列化结果:- {
- "enterpriseId": 12345,
- "kaiStatus": 0 // 直接输出 code 值
- }
复制代码 需求 3:根据不同场景返回不同值
- public enum EnterpriseAuthStatusEnum {
- PENDING(0, "pending"),
- APPROVED(1, "approved"),
- REJECTED(2, "rejected");
-
- private final int code;
- private final String text;
-
- EnterpriseAuthStatusEnum(int code, String text) {
- this.code = code;
- this.text = text;
- }
-
- // 自定义序列化器
- @JsonComponent
- public static class Serializer extends StdSerializer<EnterpriseAuthStatusEnum> {
- public Serializer() {
- super(EnterpriseAuthStatusEnum.class);
- }
-
- @Override
- public void serialize(
- EnterpriseAuthStatusEnum value,
- JsonGenerator gen,
- SerializerProvider provider
- ) throws IOException {
- // 根据业务需求选择输出字段
- gen.writeString(value.text);
- // 或 gen.writeNumber(value.code);
- }
- }
- }
复制代码 3. 全局配置方案(改变所有枚举举动)
在 application.yml 中配置:- spring:
- jackson:
- serialization:
- WRITE_ENUMS_USING_TO_STRING: true # 使用 toString() 而非 name()
复制代码 或通过 Java 配置:- @Configuration
- public class JacksonConfig {
-
- @Bean
- public Jackson2ObjectMapperBuilderCustomizer enumCustomizer() {
- return builder -> {
- // 方案1: 使用 toString()
- builder.featuresToEnable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
-
- // 方案2: 使用索引值
- // builder.featuresToEnable(SerializationFeature.WRITE_ENUMS_USING_INDEX);
- };
- }
- }
复制代码 4. 最佳实践发起
方案一:返回带说明的完整对象(推荐)
- @Data
- public class EnumDTO {
- private String name;
- private int code;
- private String description;
- }
- // 在VO中转换
- public class EnterpriseAuthStatusVO {
- private Long enterpriseId;
-
- @JsonIgnore // 隐藏原始枚举
- private EnterpriseAuthStatusEnum kaiStatus;
-
- @ApiModelProperty("客户开户状态")
- public EnumDTO getKaiStatusInfo() {
- if (kaiStatus == null) return null;
- return new EnumDTO(
- kaiStatus.name(),
- kaiStatus.getCode(),
- kaiStatus.getDescription()
- );
- }
- }
复制代码 序列化结果:- {
- "enterpriseId": 12345,
- "kaiStatusInfo": {
- "name": "PENDING",
- "code": 0,
- "description": "待审核"
- }
- }
复制代码 方案二:使用统一响应包装器
- public class ApiResponse<T> {
- private int code;
- private String message;
- private T data;
-
- // 成功响应时附加枚举元数据
- public static <T> ApiResponse<T> success(T data, EnterpriseAuthStatusEnum status) {
- ApiResponse<T> response = new ApiResponse<>();
- response.code = 200;
- response.message = status.getDescription();
- response.data = data;
- return response;
- }
- }
复制代码 5. 完整示例代码
- // 枚举定义
- @JsonFormat(shape = JsonFormat.Shape.OBJECT)
- public enum EnterpriseAuthStatusEnum {
- PENDING(0, "待审核"),
- APPROVED(1, "已通过"),
- REJECTED(2, "已拒绝");
-
- private final int code;
- private final String description;
-
- // 构造方法、getter
- }
- // VO对象
- @Data
- @EqualsAndHashCode(callSuper = false)
- @Accessors(chain = true)
- public class EnterpriseAuthStatusVO implements Serializable {
- private static final long serialVersionUID = 1L;
-
- @ApiModelProperty("企业id")
- private Long enterpriseId;
-
- @ApiModelProperty("客户开户状态")
- private EnterpriseAuthStatusEnum kaiStatus;
- }
- // 控制器
- @RestController
- public class EnterpriseController {
-
- @GetMapping("/auth/status")
- public EnterpriseAuthStatusVO getAuthStatus() {
- return new EnterpriseAuthStatusVO()
- .setEnterpriseId(10001L)
- .setKaiStatus(EnterpriseAuthStatusEnum.PENDING);
- }
- }
复制代码 请求响应:- {
- "enterpriseId": 10001,
- "kaiStatus": {
- "code": 0,
- "description": "待审核"
- }
- }
复制代码 关键总结
需求场景实现方案序列化结果示例默认举动无配置" ENDING"返回数字编码@JsonValue + getCode()0返回完整对象@JsonFormat(shape = OBJECT){"code":0, "desc":"待审核"}全局使用 toString()WRITE_ENUMS_USING_TO_STRING"待审核"自定义序列化逻辑实现 JsonSerializer任意自定义格式生产情况推荐:使用 @JsonFormat(shape = OBJECT) 返回完整枚举信息,前端可直接展示 description 字段,同时保存 code 用于逻辑判断。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |