springmvc解析的列表中的对象含有枚举_springmvc 返回的实体类有枚举如何处理-程序员宅基地

技术标签: java  

1.问题

通过http调用请求,传输的是一个对象列表,其中列表中的对象含有枚举,
发现一直无法解析成功,并抛出以下错误,很明显是枚举无法解析成功;

POST https://xxx/audit/api/v1/asyncSaveAuditLog
Content-Type: application/json;charset=utf-8

[
  {
    "sysName":"SEEWO_USERCENTER"}
]
{
    
  "timestamp": 1627466213248,
  "status": 400,
  "error": "Bad Request",
  "exception": "org.springframework.http.converter.HttpMessageNotReadableException",
  "message": "JSON parse error: Can not construct instance of java.lang.Enum: abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of java.lang.Enum: abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information\n at [Source: java.io.PushbackInputStream@4ceb6da5; line: 2, column: 14] (through reference chain: java.util.ArrayList[0]->com.seewo.audit.api.dto.SaveAuditLogQuery[\"sysName\"])",
  "path": "/audit/api/v1/asyncSaveAuditLog"
}

2.思路

1.0.暴力破解

使用@RequestBody String body来接收对象,然后再使用JSON.parseArray()解析成JSONObject,在对特殊的枚举特殊处理;但太弱智了;

1.1.Converter

后来发现Converter仅用于点对点的转换,不适用于一整个列表对象的转换,因为这样就需要你来完成json解析的工作了,因此这种方式不行;

1.2. MessageConverter

Springboot提供的一个扩展工具接口,用于解析http中@RequestBody的消息,但后来发现,就是因为原有的MessageConverter处理不了才抛出这个异常的,要想解决这个问题只能添加新的MessageConverter,手写吧,工作量较大,而且还需要测试;
后来想到可以引用FastJsonHttpMessageConverter,但发现它解析不了列表,因为我传输的是一个列表;因此这种方式不行;

1.3.@JSONField

后来了解到fastjson提供了该注解用于自定义解析规则,因此使用该注解,问题解决;

@JSONField(deserializeUsing = EnumTypeDeserializer.class)
    private Enum<AuditServiceEnum> sysName;
package com.seewo.audit.api.utils;

import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;

public class EnumTypeDeserializer implements ObjectDeserializer {
    
    private static final Logger logger = LoggerFactory.getLogger(EnumTypeDeserializer.class);

    private static final String prefixEnum = "java.lang.Enum<";

    @Override
    public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
    
        //[{"sysName":"SEEWO_USERCENTER"}]
        //其中sysName为fielName,SEEWO_USERCENTER为value
        Object value = parser.parse();
        String typeName = type.getTypeName();
        //如果是 java.lang.Enum< 开头,说明是 java.lang.Enum<com.seewo.audit.api.enums.AuditServiceEnum> 这种形式,因此需要去除前缀
        if (typeName.startsWith(prefixEnum)) {
    
            typeName = typeName.substring(prefixEnum.length(), typeName.length() - 1);
        }
        //直接反射
        try {
    
            Class<?> clazz = Class.forName(typeName);
            Method method = clazz.getMethod("valueOf", String.class);
            Object ret = method.invoke(null, value);
            return (T) ret;
        } catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
    
            logger.error("反序列化枚举失败:{}, {}", fieldName, e.getMessage());
        }
        return null;
    }

    @Override
    public int getFastMatchToken() {
    
        return 0;
    }
}

3.反思

解决这个问题花了将近4小时,哎,我还是太菜了,仍需继续努力;

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Yuan_xii/article/details/119186474

智能推荐

Windows内核原理与实现之Windows设备驱动程序_windows驱动加载原理-程序员宅基地

文章浏览阅读3.4k次。文章摘录自《Windows内核原理与实现》一书。设备驱动程序是操纵设备的内核模块,I/O 管理器、即插即用管理器和电源管理器都需要与设备的驱动程序打交道。在Windows I/O 系统中,设备驱动程序不仅为操作系统提供了支持各种 I/O 设备的能力, 也是 Windows 内核本身扩展的基础。Windows 可以动态地加载或卸载设备驱动程序,通过这些驱动程序来调整或扩展内核的功能。 Win..._windows驱动加载原理

sql篇-date、time、datetime、timestamp详解(&加减天数)_mysql日期范围-程序员宅基地

文章浏览阅读129次,点赞2次,收藏4次。timestamp 更适合来记录时间,比如我在东八区时间现在是 2021-06-08 10:23:45, 你在日本(东九区此时时间为 2021-06-08 11:23:45),我和你在聊天,数据库记录了时间,取出来之后,对于我来说时间是 2021-06-08 10:23:45,对于日本的你来说就是 2021-06-08 11:23:45。2,‘HHMMSS’格式的字符串或HHMMSS格式的数值表示,例如,输入‘123456’,Time类型会转换成12:34:56;其中,D表示天数,取值范围是0~~34。_mysql日期范围

接口测试中依赖第三方接口该如何测试?_封装在jar包的第三方接口怎么测试-程序员宅基地

文章浏览阅读2.2k次。搭建成功后,如果是使用fiddler抓包的网址,可以选中所需要的url,然后点击右边的AutoResponder tab,按照下图所示,勾选Enable rules,Accept all connections,选择find a file->选择需要调用的json文件,保存。接下来启动moco服务,打开moco-runner-1.3.0-standalone.jar所在的文件夹目录(D:\my\moco),地址栏左上角输入cmd,回车打开cmd窗口,输入以下命令。,自己模拟返回数据。_封装在jar包的第三方接口怎么测试

tensorflow 官方多GPU训练模型_tensorflow-models/tutorials/image/cifar10/cifar10_-程序员宅基地

文章浏览阅读2.1k次。tensorflow 官方多GPU训练模型标签(空格分隔): tensorflow 源码caffe如果用到多GPU训练,则需要进行编译配置MPI,而且很容易报错,tensorflow只需要在代码中使用即可。官方给的代码:# Copyright 2015 The TensorFlow Authors. All Rights Reserved.## Licensed un..._tensorflow-models/tutorials/image/cifar10/cifar10_multi_gpu_train.py

linux命令之yum、screen_yum screen-程序员宅基地

文章浏览阅读5.1k次,点赞4次,收藏4次。一、yum命令安装程序screen[root@localhost ~]# yum install screen -y解释:-y表示中间有提示的地方都选择yes,也可以不加-y参数卸载程序screen[root@localhost ~]# yum remove screen -y查看程序screen的信息[root@localhost ~]# yum info screen显示程序..._yum screen

android 夜神,全球首个安卓9模拟器即将问世-程序员宅基地

文章浏览阅读606次。夜神模拟器在模拟器行业率先破圈,即将全球首发安卓9 内核模拟器,目前已确认可运行《原神》、《盾之勇者成名录RERISE》等需要安卓8以上环境才能运行的热门手游。强劲的市场表现,离不开技术的深耕。在过去一年多时间里,夜神模拟器团队专注于安卓9架构进行研究与适配,并深入安卓模拟器内核,适配Windows指令编码,进行深度优化,终于解决了困扰很多大型3D游戏玩家的难题。据悉,NOX旗下夜神模拟器团队成立..._夜神模拟器无法安装安卓9

随便推点

android 中 MVC框架_android中mvc框架-程序员宅基地

文章浏览阅读3.5k次。在Android应用程序中,我们不能够非常清楚地区分MVC结构中的视图部分和控制器部分。Android框架期望开发者们将Activity基础类作为UI处理,这也就意味着一个Activity需要负责视图与控制器两个部分的任务。利用观察者模式将Model进行绑定处理。Andr_android中mvc框架

Colab防断,防止colab每隔一段时间自动断连。-程序员宅基地

文章浏览阅读7.8k次,点赞3次,收藏6次。通过设置Colab自动点击网页,防止断连Colab目前30min会自动断开运行程序,如下方法可以解决该问题,亲测有效。按Ctrl+ Shift + i 或者F12打开浏览器控制台,找到console,在其中输入:function KeepClicking(){ console.log("Clicking"); document.querySelector("colab-toolbar-button#connect").click()}setInterval(KeepClicking,6000_colab防断

M1 MacBook的环境安装_type a and press return to agree-程序员宅基地

文章浏览阅读883次。这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入欢迎使用Markdown编辑器你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Mar_type a and press return to agree

关于匿名者组织(Anonymous),你都知道哪些?-程序员宅基地

文章浏览阅读566次。根据最新的消息称,黑客组织匿名者比你想象的规模还要庞大,同时匿名者也开始变得“众所周知”,之前他们面向社会以及媒体的时候,匿名者成员都戴着盖伊·福克斯面具,同时该黑客组织成员称呼自己组织为“匿名者”,而这种做法也确实“名副其实”。匿名者成员们在每次对外活动中都会戴上面具,现在匿名者知名度也是很高的。目前类似这样的组织进行的活动在很大程度上被认为是非法的..._幽灵安全团队

二维旋转矩阵公式推导_二阶矩阵的旋转变换公式是啥-程序员宅基地

文章浏览阅读1.5w次,点赞4次,收藏18次。这篇博文来推导一下旋转矩阵。首先来假设 OP1旋转到了OP2,逆时针矩阵推导。当然也有顺时针矩阵推导。然后有没有什么办法可以不考虑顺时针逆时针?这里我考虑了一下OP1和OP2不相等的情况因为先求的sin(theta),如果是逆时针,theta就是正值,如果是顺时针,theta就是负值。之前我的想法,求theta,是先根据三角形的边长求夹角的公式求的cos(theta)..._二阶矩阵的旋转变换公式是啥

五款出色的产品原型设计工具推荐-程序员宅基地

文章浏览阅读808次,点赞16次,收藏23次。传统的产品原型设计工具不仅会使计算机频繁“闪光”,而且非常“懒惰”,使设计效率自动扶梯下降!基于云运行的新一代在线协作产品原型设计工具的即时设计,无论是在设计层功能还是内存配置要求上,都完美地实现了高效产品原型设计的工作理念,无需下载即可使用,一键交付,支持多层同步设计,“云”、“通用性”、“协作”一统拿下!导入Axure格式扭曲乏味?别担心!产品原型设计工具即时设计的[Axure演示文件]格式功能可以一键导入Axure文件HTML静态格式,100%保留交互效果。