1、使用mybatis-plus,指定枚举类所在的的包
SpringBoot工程在
application.yml中增加
mybatis-plus:
type-enums-package: com.xxx.xxx.model.enums
2、实现mybatisplus提供的IEnum接口,重写getValue()方法
package com.xxx.xxx.model.enums;
import com.baomidou.mybatisplus.core.enums.IEnum;
/**
* <p>
* 用户状态枚举
* </P>
* @author frank
* @date 2019/7/11 19:05
*/
public enum UserState implements IEnum {
/**
* 正常
*/
NORMAL(10, "正常"),
/**
* 锁定
*/
LOCKED(20, "锁定"),
/**
* 失效
*/
INVALID(30, "失效"),
/**
* 异常
* */
ABNORMAL(40, "异常"),
/**
* 未激活
* */
NOT_ACTIVE(50, "未激活");
private int value;
private String desc;
UserState(final int value, String desc) {
this.value = value;
this.desc = desc;
}
@Override
public Integer getValue() {
return this.value;
}
@Override
public String toString(){
return desc;
}
}
3、将SpringMVC的JSON解析器设置为fastjson
package com.xxx.xxx.config.fastjson;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.ToStringSerializer;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
/**
* <p>
* fastjson序列化配置
* </P>
* @author frank
* @date 2019-10-12 18:33
*/
@Configuration
public class FastJsonMvcConfig implements WebMvcConfigurer {
private static final String DEFAULT_CHARSET = "UTF-8";
private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:SS";
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
List<MediaType> mediaTypes = new ArrayList<>();
mediaTypes.add(MediaType.APPLICATION_JSON);
mediaTypes.add(MediaType.TEXT_HTML);
mediaTypes.add(new MediaType("application", "xml"));
mediaTypes.add(new MediaType("text", "xml"));
mediaTypes.add(new MediaType("application", "*+xml"));
mediaTypes.add(MediaType.ALL);
fastJsonHttpMessageConverter.setSupportedMediaTypes(mediaTypes);
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setCharset(Charset.forName(DEFAULT_CHARSET));
fastJsonConfig.setDateFormat(DEFAULT_DATE_FORMAT);
SerializerFeature[] serializerFeatures = new SerializerFeature[] {
//格式化输出
SerializerFeature.PrettyFormat,
//输出空置
SerializerFeature.WriteMapNullValue,
//空集合输出空数组[]
SerializerFeature.WriteNullListAsEmpty,
//日期格式化
SerializerFeature.WriteDateUseDateFormat,
//枚举输出
SerializerFeature.WriteEnumUsingToString
};
fastJsonConfig.setSerializerFeatures(serializerFeatures);
SerializeConfig serializeConfig = SerializeConfig.globalInstance;
serializeConfig.put(BigInteger.class, ToStringSerializer.instance);
serializeConfig.put(Long.class, ToStringSerializer.instance);
serializeConfig.put(Long.TYPE, ToStringSerializer.instance);
fastJsonConfig.setSerializeConfig(serializeConfig);
fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
converters.add(fastJsonHttpMessageConverter);
}
}
4、使用fastjson反序列化枚举类型
如果是IEnum类型,则先根据getValue()进行匹配,然后根据toString()进行匹配,如果都没有匹配到,再按照名字或者枚举类的序号进行匹配。
package com.xxx.xxx.config.fastjson;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.parser.JSONLexer;
import com.alibaba.fastjson.parser.JSONToken;
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
import com.baomidou.mybatisplus.core.enums.IEnum;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
/**
* fastJson反序列化枚举类型
*
* @author frank
* @date 2020/2/25 15:23
*/
@Slf4j
public class FastJsonEnumDeserializer implements ObjectDeserializer {
@Override
public <T> T deserialze(DefaultJSONParser parser, Type type, Object o) {
final JSONLexer lexer = parser.lexer;
final int token = lexer.token();
Class cls = (Class) type;
Object[] enumConstants = cls.getEnumConstants();
if (IEnum.class.isAssignableFrom(cls)) {
// IEnum类型
try {
// 根据getValue()进行取值
Method getValueMethod = cls.getMethod("getValue");
Class returnType = getValueMethod.getReturnType();
if (Integer.class.equals(returnType) || int.class.equals(returnType)) {
if (token == JSONToken.LITERAL_INT) {
for (Object enumConstant : enumConstants) {
IEnum<Integer> baseEnum = (IEnum<Integer>) enumConstant;
Integer value = baseEnum.getValue();
if (lexer.intValue() == value) {
return (T) baseEnum;
}
}
}
}
}catch (NoSuchMethodException e){
e.printStackTrace();
}
try {
// 根据toString()进行取值
Method getValueMethod = cls.getMethod("toString");
Class returnType = getValueMethod.getReturnType();
if (String.class.equals(returnType)) {
if (token == JSONToken.LITERAL_STRING) {
for (Object enumConstant : enumConstants) {
IEnum baseEnum = (IEnum) enumConstant;
String str = baseEnum.toString();
if (null != str && str.equals(lexer.stringVal())) {
return (T) baseEnum;
}
}
}
}
}catch (NoSuchMethodException e){
e.printStackTrace();
}
}
// 默认按名字或者按ordinal取值
if (token == JSONToken.LITERAL_INT) {
// 按ordinal取值
int intValue = lexer.intValue();
lexer.nextToken(JSONToken.COMMA);
if (intValue < 0 || intValue > enumConstants.length) {
throw new JSONException(String.format("parse enum %s error, value : %s", cls.getName(), intValue));
}
return (T) enumConstants[intValue];
} else if (token == JSONToken.LITERAL_STRING) {
// 按名字取值
return (T) Enum.valueOf(cls, lexer.stringVal());
}
return null;
}
@Override
public int getFastMatchToken() {
return JSONToken.LITERAL_INT;
}
}
5、在成员变量上增加 @JSONField注解,使用deserializeUsing指定反序列化类
@JSONField(deserializeUsing = FastJsonEnumDeserializer.class)
package com.xxx.xxx.vo;
import com.alibaba.fastjson.annotation.JSONField;
import com.xxx.xxx.model.enums.UserState;
import com.xxx.xxx.config.fastjson.FastJsonEnumDeserializer;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* @author frank
* @date 2019/9/6
*/
@ApiModel
@Data
public class UserInfoVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键id")
private String id;
@ApiModelProperty(value = "用户账号")
private String userAccount;
@ApiModelProperty(value = "用户状态")
@JSONField(deserializeUsing = FastJsonEnumDeserializer.class)
private UserState userState;
}