解决bug:HttpMessageNotReadableException: JSON parse error: java.lang.Object is not an enum type
完整的问题如下:
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"
]
}
结果可以显示
结论是:普通的枚举类可以通过
“字段”:[“枚举的属性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反序列化配置里面去改
还没有评论,来说两句吧...