zoukankan      html  css  js  c++  java
  • SpringBoot 处理 POST Json 传参枚举

    在 Spring 框架中对枚举类型的序列化/反序列化是有限制的。

    假设如下面这样在某些情况下就不能正常工作:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public enum PayChannelEnum implements BaseEnum<Integer> {

    ALIPAY(20),

    WECHARPAY(21);

    private Integer code;

    }

    比如对于具有 PayChannelEnum 类型的参数的 HTTP 接口来说:

    如果请求 /get?payChannel=ALIPAY,运行OK。但如果请求 /get?payChannel=20, 就会抛出 MethodArgumentTypeMismatchException 异常。

    日常开发中主要有如下几种场景使用枚举:

    1. GET 方法, 参数列表中有枚举类型/自定义参数包含枚举;
    2. POST 方法 Form表单
    3. POST 方法 Json传参;

    一般我们有如下步骤:

    1. 实现ConverterFactory接口
    2. 注册转换器

    代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    public class  implements ConverterFactory<String, BaseEnum> {

    private static final Map<Class,Converter> CONVERTER_MAP=new HashMap<>();


    public <T extends BaseEnum> Converter<String, T> getConverter(Class<T> aClass) {
    Converter converter=CONVERTER_MAP.get(aClass);
    if(converter==null){
    converter=new IntegerStrToEnumConverter<>(aClass);
    CONVERTER_MAP.put(aClass, converter);
    }
    return converter;
    }


    class IntegerStrToEnumConverter<T extends BaseEnum> implements Converter<String, T> {

    private Map<String,T> enumMap=new HashMap<>();

    private IntegerStrToEnumConverter(Class<T> enumType){
    T[] enums=enumType.getEnumConstants();
    for (T e:enums){

    enumMap.put(e.getCode()+"",e);
    enumMap.put(((Enum)e).name()+"",e);
    }
    }


    大专栏  SpringBoot 处理 POST Json 传参枚举"line"> public T convert(String source) {
    T result=enumMap.get(source);
    if(result==null){
    //枚举字面量进行映射
    throw new IllegalArgumentException("No element matches "+source);
    }
    return result;
    }
    }

    }

    但针对Json传参,传递值时机会解析报错,可以通过设置 @JsonCreator@JsonValue来设定默认的反序列化方法. 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    public enum PayChannelEnum implements BaseEnum<Integer> {

    ALIPAY(20),

    WECHARPAY(21);

    private Integer code;

    PayChannelEnum(int code) {
    this.code = code;
    }

    @JsonCreator
    public static PayChannelEnum create(String name) {
    try{
    return PayChannelEnum.valueOf(name);
    }catch (IllegalArgumentException e){
    int code=Integer.parseInt(name);
    for (PayChannelEnum value : PayChannelEnum.values()) {
    if(value.code==code){
    return value;
    }
    }
    }
    throw new IllegalArgumentException("No element matches "+name);
    }

    public void setCode(Integer code) {
    this.code = code;
    }


    public Integer getCode() {
    return code;
    }
    }

    抽取范型,方便多种类型枚举

    1
    2
    3
    4
    5
    6
    public interface BaseEnum<T> {

    @JsonValue
    T getCode();

    }

    经过改造,就可以支持所有场景的枚举解析。

  • 相关阅读:
    Android Layout XML属性
    linux]ubuntu挂载U盘
    Android之NDK开发
    Android 创建永不Kill的Service
    如何编写可移植的c/c++代码
    Android写日志文件类
    Android Activity去除标题栏和状态栏
    linux .bash_profile和.bashrc的什么区别
    ListView.setOnItemClickListener、setOnCreateContextMenuListener无效 为什么
    WCF 第四章 绑定 使用队列技术进行通信
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12325406.html
Copyright © 2011-2022 走看看