当前位置: 代码迷 >> 综合 >> 解决bug:HttpMessageNotReadableException: JSON parse error: java.lang.Object is not an enum type
  详细解决方案

解决bug:HttpMessageNotReadableException: JSON parse error: java.lang.Object is not an enum type

热度:39   发布时间:2023-09-27 02:14:40.0

完整的问题如下:

swagger模拟前端请求的json格式为:

{"enabled": true,"identification": "string","name": "string","onwerRoleGroups": [null],"parentId": 0,"remark": "string","roleCategory": "NORMAL","root": true,"text": "string","totalResources": [{"enabled": true,"id": 0,"operations": ["RETRIEVE"],"permissionModule": {"enabled": true,"identification": "string","menu": true,"name": "string","ownerType": "ROLE","parentId": 0,"rank": 0,"remark": "string","root": true,"uris": ["string"]},"rank": 0}]
}

问题出在:

"operations": ["RETRIEVE"]

详细的报错为:

— Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: java.lang.Object is not an enum type; nested exception is com.fasterxml.jackson.databind.JsonMappingException: java.lang.Object is not an enum type (through reference chain: cn.ffcs.videoapp.web.security.permission.entity.PermissionRole[“totalResources”]->java.util.HashSet[0]->cn.ffcs.videoapp.web.security.permission.entity.PermissionResource[“operations”]->java.util.HashSet[0])]
分析的话应该是枚举和javabean识别的问题
先做一个简单的DEMO测试一下
下面的代码是controller

    @ApiOperation("呵呵")@PostMapping("/aaa")public String addRole1(@RequestBody Person2 person2) {Set<Sex> sexs = person2.getSexs();System.out.println(person2.getName());for (Sex sex : sexs) {System.out.println(sex.getText());}return "ok";}

下面的封装一个javabean,里面一个字段是Set<枚举>

public class Person2 {private Set<Sex> sexs=new HashSet<>(0);private String name;public Set<Sex> getSexs() {return sexs;}public void setSexs(Set<Sex> sexs) {this.sexs = sexs;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}

这个是枚举

public enum Sex {MAN("男"),WOMAN("女");private String text;Sex(String text) {this.text = text;}public String getText() {return text;}public void setText(String text) {this.text = text;}public static void main(String[] args) {System.out.println(Sex.MAN.getText());}
}

swagger里面的json是:

{"name": "string","sexs": ["MAN"]
}

结果可以显示
解决bug:HttpMessageNotReadableException: JSON parse error: java.lang.Object is not an enum type
结论是:普通的枚举类可以通过
"字段":[“枚举的属性1”,“枚举的属性2”]
入参给controller并进行解析
但是同样的写法.复杂嵌套的java里面套java再套枚举就不行
在网上查询资料:
https://blog.csdn.net/zhangfengaiCQ/article/details/82657926#commentBox
再枚举上加上注解
@JSONType(serializeEnumAsJavaBean = true)
(import com.alibaba.fastjson.annotation.JSONType;)
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
(import com.fasterxml.jackson.annotation.JsonFormat;)
然后再枚举类上加上这两个注解,发现就可以了

找一下为什么

@JSONType(serializeEnumAsJavaBean = true)
作用:配置enum的序列化,可以加在类上,也可以在SerializeConfig 里面配置
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
作用:
(1)@JsonFormat 用来表示json序列化的一种格式或者类型,主要有下面几个常用的属性
shape: 表示序列化后的一种类型

pattern: 表示日期的格式

timezone: 默认是GMT,中国需要GMT+8

locale: 根据位置序列化的一种格式
(2)可用于controller返回给前端responsebody的时候把枚举转换为Object

参考资料

https://segmentfault.com/q/1010000006935643?_ea=1182544
https://blog.csdn.net/u012326462/article/details/83019681
https://blog.csdn.net/zhangfengaiCQ/article/details/82657926#commentBox

思考测试了下.好像有点不对

@JSONType(serializeEnumAsJavaBean = true)好像是没用的
只要@JsonFormat(shape = JsonFormat.Shape.OBJECT)就可以了
本项目之前用的枚举类继承了的类里面已经加了@JsonFormat(shape = JsonFormat.Shape.OBJECT)
本来是可以了.
继承的类上加了

@JsonDeserialize(using = OptionEnumAwareDeserializer.class
)
@JsonFormat(shape = Shape.OBJECT
)
public class OptionEnumAwareDeserializer extends JsonDeserializer<OptionEnumAware>

估计改变了json的反序列化的配置规则,所以导致错误
这里序列化指 对象转json字符串
反序列化指string的json转对象
具体还是要去json反序列化配置里面去改

  相关解决方案