在 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(); }

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

SpringBoot 处理 POST Json 传参枚举的更多相关文章

  1. json传参应用

    json传参应用 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.JSON采用完全独立于语言的文本格式,这些特性使JSON成为理想的数据交换语言.易于人阅 ...

  2. ASP.NET WebAPI RC 竟然不支持最常用的json传参

    壮士断腕(WCF Web API),为的是 ASP.NET Web API 的横空出世,再加上它的开放(开源),于是对之产生了一点点痴情,并写下了HttpClient + ASP.NET Web AP ...

  3. HttpClient调用doGet、doPost、JSON传参及获得返回值

    调用 doPost:map传参 Map<String,Object> map = new HashMap<>(); map.put("test"," ...

  4. json传参 js前端和java后端 的简单例子

    下面讲解了从前端js对象-->json字符串-->java字符串---->java map的过程 1,初始化js对象 var param = {}; param.krel = kre ...

  5. 关于SQL Server 2017中使用json传参时解析遇到的多层解析问题

    开发新的系统,DB部分使用了SQL Server从2016版开始自带的Json解析方式. 用了快半年,在个人项目,以及公司部分项目上使用了,暂时还没遇到大的问题,和性能问题. 今天在解析Json的多级 ...

  6. JSON传参

    通过javascript将数据组织成json格式,然后传到java后台. 注意:前台json数组传参到后台时候需要将对象(json或json数组)转换成字符串(字符串数组). Simple: 1.前台 ...

  7. json传参报错

    restful接口报错: com.fasterxml.jackson.core.JsonParseException: Unexpected character ('e' (code 101)): w ...

  8. jquery 巧用json传参

    JavaScript代码,巧用JSON传参数function AddComment(content) { var comment = {}; comment.threadId = $("#s ...

  9. [2019/05/17]解决springboot测试List接口时JSON传参异常

    报错信息,大致如下 c.c.c.c.a.BaseControllerExceptionHandler : 运行时异常: java.lang.IllegalStateException: No prim ...

随机推荐

  1. Linux-父进程wait回收子进程

    1.wait工作原理 (1).子进程结束时,系统向其父进程发送SIGCHILD信号 (2).父进程调用wait函数后阻塞 (3).父进程被SIGCHILD信号唤醒然后去回收僵尸子进程 (4).父子进程 ...

  2. Tomcat远程debug配置

    当我们需要定位生产环境问题,而日志又不清晰的情况下,我们可以借助Tomcat提供的远程调试,设置如下: // Linxu系统: apach/bin/startup.sh开始处中增加如下内容: decl ...

  3. windows 安装MySQL服务 zip解压程序

    1:配置 my.ini 文件 如下: [mysql] default-character-set=utf8[mysqld] port=3306basedir=D:\\Program Files\\da ...

  4. Python基础——类new方法与单例模式

    介绍: new方法是类中魔术方法之一,他的作用是给类实例化开辟一个内存地址,并返回一个实例化,再由__init__对这个实例进行初始化,故它的执行肯定就是在初始化方法__init__之前了.new方法 ...

  5. mysql免安装版 win10

    1.在官网中下载免安装版:https://dev.mysql.com/downloads/mysql/ 2.解压下载后的文件,新建 data 文件夹和 my.ini 文件  3.打开 my.ini 文 ...

  6. Java复习(三)类中的方法

    3.1方法的控制流程 与C/C++类似 3.2异常处理 Java处理错误的方法 抛出(throw)异常 在方法的运行过程中,如果发生了异常,则该方法生成一个代表该异常的代码并把它交给运行时系统,运行时 ...

  7. Matlab高级教程_第三篇:Matlab转码C/C++方式(混编)_第二部分

    这一部分通过一些实例来进行转码和调试的讲解: 1. 输入变量.输出变量和过程内变量的内存预分配 函数代码:函数名test function [A,B] = test( mark,num,array ) ...

  8. HDU-4614 Vases and Flowers(线段树区间更新+二分查找)

    http://acm.hdu.edu.cn/showproblem.php?pid=4614 Time Limit: 4000/2000 MS (Java/Others)    Memory Limi ...

  9. USACO 2009 Open 干草塔 Tower of Hay(贪心+单调队列优化DP)

    https://ac.nowcoder.com/acm/contest/1072/B Description 为了调整电灯亮度,贝西要用干草包堆出一座塔,然后爬到牛棚顶去把灯泡换掉.干草包会从传送带上 ...

  10. struts.xml中namespace的配置之浏览器兼容性

    还是做练习项目的时候发现一个问题: <span style="font-size:14px;"><package name="default" ...