博文首发地址:https://blog.virde.xyz

Springboot传参时通过注解转换RequestBody中的枚举类型

请求对象为@RequestBody MyRequest request时,MyReqeust中包含了枚举类型。
如果不加处理,前端只能传递枚举名或者枚举数组下标。
经过改造,可以传递自已定义的枚举值。

参考文章:https://blog.csdn.net/liuxinghao/article/details/119881628

具体实现步骤

  1. 定义基本枚举类
public interface BaseEnum {
    Integer getCode();

}
  1. 定义Jackson解析器
public class CodeToEnumDeserializer extends JsonDeserializer<BaseEnum> {

    @Override
    public BaseEnum deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
            throws IOException {
        final Integer param = jsonParser.getIntValue();// 1
        final JsonStreamContext parsingContext = jsonParser.getParsingContext();// 2
        final String currentName = parsingContext.getCurrentName();// 3
        final Object currentValue = parsingContext.getCurrentValue();// 4
        try {
            final Field declaredField = currentValue.getClass().getDeclaredField(currentName);// 5
            final Class<?> targetType = declaredField.getType();// 6
            final Method valuesMethod = targetType.getDeclaredMethod("values");// 7
            BaseEnum[] enums = (BaseEnum[]) valuesMethod.invoke(null);
            for (BaseEnum anEnum : enums) {
                if(anEnum.getCode().equals(param)){
                    return anEnum;
                }
            }
            throw new RuntimeException("不匹配");
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException | NoSuchFieldException e) {
            throw new RuntimeException("不匹配",e);
        }
    }
}
  1. 业务中的枚举类,需要继承BaseEnum
@Getter
@ToString
@AllArgsConstructor
@JsonFormat(shape=JsonFormat.Shape.OBJECT)
public enum OrderStatusEnum implements BaseEnum {

    NEW(1,"新建"),
    SEND(2,"配送"),
    RECEIVE(3,"收货"),
    DONE(4,"完成");

    private Integer code;
    private String name;

}
  1. 定义请求类,在枚举类上添加 @JsonDeserialize(using = CodeToEnumDeserializer.class)
@Data
@ToString
public class MyEnumRequest {

    private String orderSn;

    @JsonDeserialize(using = CodeToEnumDeserializer.class)
    private OrderStatusEnum orderStatus;

}
  1. 定义接口,进行测试
@PostMapping("enum-request")
public Rsp<MyEnumRequest> enumRequest(@RequestBody MyEnumRequest enumRequest){
    log.info("请求参数:{}",enumRequest);
    return Rsp.success(enumRequest);
}

具体请求返回如下:

// 请求参数
{
  "orderSn": "123",
  "orderStatus": 3
}

// 返回参数
{
  "code": 0,
  "mark": null,
  "info": "",
  "data": {
    "orderSn": "123",
    "orderStatus": {
      "code": 3,
      "name": "收货"
    }
  },
  "values": null,
  "success": true
}

总结

先定义BaseEnumCodeToEnumDeserializer解析器,在具体的业务枚举上添加@JsonDeserialize(using = CodeToEnumDeserializer.class)注解,即可实现需求。

posted @ 2022-10-09 10:03  黑风风  阅读(1808)  评论(0编辑  收藏  举报

博文首发地址:https://blog.virde.xyz