报错
json反序列化异常。JSON parse error: Cannot deserialize value of type `com.XXXX.RelationTypeEnum` from String "111": not one of the values accepted for Enum class: [A, B]; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `com.XXXX.RelationTypeEnum` from String "111": not one of the values accepted for Enum class: [A, B]
需求
新增记录时,前端传入字符串aaa,数据库节约空间存1。查询详情时,读取数据库的1,返回给前端需要返回aaa,不能返回1
用法总结
----------------------------------------------------插播小知识------------------------------------------------
序列化:序列化为json,java对象->json
反序列化:json->java对象
----------------------------------------------------回到正轨------------------------------------------------
解决方案
这种情况,一般用枚举。
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
public enum RelationTypeEnum {
A("aaa", "111", 1),
B("bbb", "222", 2),
;
@JsonValue // json序列化、反序列化的值。主要针对前端的输入和输出
private final String value;
private final String value1;
@EnumValue // mysql存储的值
private final int code;
RelationTypeEnum(String value, String value1, int code) {
this.value = value;
this.value1 = value1;
this.code = code;
}
public String getValue() {
return value;
}
public int getCode() {
return code;
}
public String getValue1() {
return value1;
}
}
场景罗列:
@JsonValue作用:
1、将字符串反序列化为枚举实例
前端传入字符串aaa,后端需要生成对应的枚举实例A。aaa会与所有实例的@JsonValue所在字段(上图中是value)做比较,如果一样,就获取该枚举实例。
2、将枚举实例序列化为字符串
后端枚举实例A,返回给前端aaa。
@EnumValue作用:
对于一个枚举实例A,数据库存的值是@EnumValue所在字段的值,也就是1。
@JsonCreator作用:
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
public enum RelationTypeEnum {
A("aaa", "111", 1),
B("bbb", "222", 2),
;
@JsonValue // json序列化、反序列化的值。主要针对前端的输入和输出
private final String value;
private final String value1;
@EnumValue // mysql存储的值
private final int code;
RelationTypeEnum(String value, String value1, int code) {
this.value = value;
this.value1 = value1;
this.code = code;
}
@JsonCreator // json反序列化方法。前端传入string,后端会根据打了@JsonCreator的方法生成对应的枚举
public static RelationTypeEnum fromValue(String v) {
for (RelationTypeEnum en : RelationTypeEnum.values()) {
if (en.value1.equals(v)) {
return en;
}
}
return null;
}
public String getValue() {
return value;
}
public int getCode() {
return code;
}
public String getValue1() {
return value1;
}
}
打在方法上,不能打在字段上,如下图。把字符串反序列化为枚举时会用到这个方法。前端传入aaa,根据方法代码可知,遍历枚举实例,如果value1等于aaa,则获取该枚举实例。
如果不加@JsonCreator,则反序列化会用到@JsonValue,如果加了@JsonCreator,则优先用@JsonCreator
啥都不加
如果@EnumValue、@JsonValue、@JsonCreator都不加,就是个普通的枚举。前端需要传数值(即实例的索引值),比如0,然后后端会获取到0索引所在的枚举实例,也就是A。mysql存储的是A(枚举名称),返回给前端的也是A。