SpringBoot的JackJson枚举国际化

0. 整个工具的代码都在Gitee或者Github地址内

gitee:solomon-parent: 这个项目主要是总结了工作上遇到的问题以及学习一些框架用于整合例如:rabbitMq、reids、Mqtt、S3协议的文件服务器、mongodb

github:GitHub - ZeroNing/solomon-parent: 这个项目主要是总结了工作上遇到的问题以及学习一些框架用于整合例如:rabbitMq、reids、Mqtt、S3协议的文件服务器、mongodb

1. 新增基础枚举接口

public interface BaseEnum<T> {

  /**
   * 获取I8N国际化key
   */
  String key();

  /**
   * 获取存入数据库的值
   */
  T label();

  /**
   * 获取描述
   */
  String getDesc();

  /**
   * 获取I18N国际化信息
   *
   * @return 国际化信息
   */
  default String Desc() {
    return I18nUtils.getEnumMessage(getClass().getSimpleName()+"."+key());
  }
}

该类中的Desc是根据I18n获取国际化值,各位按照项目要求稍作调整

2. 新增枚举工具类

public class EnumUtils {

    /**
     * 判断枚举是否存在
     *
     * @param enumClass 枚举类
     * @param object    枚举值
     * @return true 有枚举值 false 没有枚举值
     */
    public static boolean exist(Class<? extends Enum<?>> enumClass, Object object) {
        if (ValidateUtils.isEmpty(object)) {
            return false;
        }
        if (object instanceof Collection) {
            Collection<Object> collections = (Collection<Object>) object;
            for (Object o : collections) {
                Object enums = codeOf(enumClass, o);
                if (ValidateUtils.isEmpty(enums)) {
                    return false;
                }
            }
            return true;
        } else {
            return !ValidateUtils.isEmpty(codeOf(enumClass, object));
        }
    }

    /**
     * 获取枚举类
     *
     * @param enumClass 枚举对象类
     * @param value     枚举值
     * @return 返回枚举类
     */
    public static <E extends Enum<?> & BaseEnum<?>> E codeOf(Class<? extends Enum<?>> enumClass, Object value) {
        if (ValidateUtils.isEmpty(value)) {
            return null;
        }
        E[] enumConstants = (E[]) enumClass.getEnumConstants();
        for (E e : enumConstants) {
            if (e.label().equals(String.valueOf(value)) || e.name().equals(String.valueOf(value))) {
                return e;
            }
        }
        return null;
    }
}

EnumUtils中的ValidateUtils可以用hutool的ObjectUtil替换

3. 然后新增枚举转换注解

/**
 * 枚举序列化返回参数
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@JacksonAnnotationsInside
@JsonSerialize(using = JacksonSerializer.class)
public @interface JsonEnum {

    Class<? extends Enum<?>> enumClass();

    /**
     * 调用enumClass的Get方法,然后在返回字段后面添加后缀
     */
    String methodName() default BaseMethodNameEnum.DESCRIPTION;

    /**
     * 如果自定义字段返回,则可以增加此字段返回
     */
    String fieldName() default "";

    /**
     * 是否输出这个结果
     */
    boolean ignore() default true;
}

4. 新增jackJson转换器

public class JacksonSerializer extends JsonSerializer<String> implements ContextualSerializer {

    private final Logger logger = LoggerUtils.logger(getClass());

    private Class<? extends Enum<?>> enumClass;

    private String prefix;

    private String methodName;

    private String fieldName;

    public JacksonSerializer() {
        super();
    }

    public JacksonSerializer(Class<? extends Enum<?>> enumClass, String prefix, String methodName, String fieldName) {
        this.enumClass = enumClass;
        this.prefix = prefix;
        this.methodName = methodName;
        this.fieldName = fieldName;
    }

    @Override
    public void serialize(String o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
            throws IOException {

        jsonGenerator.writeString(o);
        try {
            Enum<?> enums = EnumUtils.codeOf(enumClass, o);
            if (ValidateUtils.isEmpty(enums)) {
                logger.error("EnumSerializer 转换枚举为空,值:{},类名:{}", o, enumClass.getName());
                return;
            }
            String value = (String) enumClass.getMethod(methodName).invoke(enums);
            if (ValidateUtils.isEmpty(fieldName)) {
                jsonGenerator.writeStringField(prefix + methodName, value);
            } else {
                jsonGenerator.writeStringField(fieldName, value);
            }
        } catch (Throwable e) {
            logger.error("EnumSerializer 转换失败,值:{},枚举类为:{},调用方法名为:{}报错异常为 e:", o, enumClass.getName(), methodName, e);
            return;
        }
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty)
            throws JsonMappingException {
        if (ValidateUtils.isEmpty(beanProperty)) {
            return serializerProvider.findNullValueSerializer(beanProperty);
        }

        if (!Objects.equals(beanProperty.getType().getRawClass(), String.class)) {
            return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }

        JsonEnum enumLabel = beanProperty.getAnnotation(JsonEnum.class);
        if (ValidateUtils.isEmpty(enumLabel) || !enumLabel.ignore()) {
            return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }
        return new JacksonSerializer(enumLabel.enumClass(), beanProperty.getName(), enumLabel.methodName(), enumLabel.fieldName());
    }
}

这样子之后在返回结果集后会将枚举国际化返回

5. 测试Demo

​​​​​​​

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值