首页 > 其他分享 >自定义注解获取属性对应枚举的翻译值

自定义注解获取属性对应枚举的翻译值

时间:2024-06-10 21:00:35浏览次数:9  
标签:enumClass 自定义 enumShow 枚举 EnumShow 注解 序列化

平时在开发的时候难免会遇到枚举来翻译类,于是写一个自定义注解来在开发的时候自动翻译枚举的值
相关代码如下:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@JacksonAnnotationsInside
public @interface EnumShow {
    /**
     * 要转换成的枚举
     *
     * @return
     */
    Class<? extends BaseEnum<?>> enumClass();

    /**
     * 如果不复写本身新增字段是本身字段的增加的后缀
     *
     * @return
     */
    String suffix() default "Str";


}

这段Java代码定义了一个名为EnumShow的注解,用于标注字段。该注解有以下功能:
enumClass属性指定要将字段转换成的枚举类,该枚举类需要继承自BaseEnum。
suffix属性指定当新增字段时,字段名称的后缀,默认为"Str"。
这个注解的作用是配合Jackson库将标注了该注解的字段序列化为指定枚举类的JSON格式。

@JsonComponent
public class EnumShowIntegerSerializer extends JsonSerializer<Integer> implements ContextualSerializer {

    private EnumShow enumShow;

    public EnumShowIntegerSerializer() {

    }

    public EnumShowIntegerSerializer(final EnumShow enumShow) {
        this.enumShow = enumShow;
    }

    /**
     * 序列化整数枚举值。
     * 根据枚举类的实现情况,决定如何序列化枚举值。
     * 如果枚举类实现了BaseEnum接口,直接通过接口方法获取描述。
     * 如果枚举类没有实现BaseEnum接口,通过反射调用getKey和getValue方法获取描述。
     * 
     * @param integer   需要序列化的整数枚举值。
     * @param jsonGenerator   用于生成JSON的工具。
     * @param serializerProvider   序列化提供者,用于获取其他序列化器。
     * @throws IOException 如果序列化过程中发生I/O错误。
     */
    @SneakyThrows
    @Override
    public void serialize(Integer integer, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {

        if (null == integer || null == enumShow) {
            jsonGenerator.writeObject(integer);
            return;
        }
        String fieldName = jsonGenerator.getOutputContext().getCurrentName();
        Class<?>[] interfaces = enumShow.enumClass().getInterfaces();
        String theMsg = null;
        if (interfaces.length > 0) {
            Class<?> baseInterface = interfaces[0];
            if (baseInterface.equals(BaseEnum.class)) {
                Class newIns = enumShow.enumClass();
                Optional<? extends BaseEnum<?>> enumOpt = BaseEnum.of(newIns, integer);
                if (enumOpt.isPresent()) {
                    theMsg = enumOpt.get().getValue();
                }
            }
        } else {
            if (enumShow.enumClass().isEnum()) {
                Method codeMethod = enumShow.enumClass().getDeclaredMethod("getKey");
                Method descMethod = enumShow.enumClass().getDeclaredMethod("getValue");
                for (Object obj : enumShow.enumClass().getEnumConstants()) {
                    if (integer.equals(codeMethod.invoke(obj))) {
                        theMsg = descMethod.invoke(obj).toString();
                    }
                }
            }
        }
        jsonGenerator.writeNumber(integer);
        jsonGenerator.writeStringField(fieldName + enumShow.suffix(), theMsg);
    }

    /**
     * 根据上下文创建自定义的序列化器。
     * 如果属性上有EnumShow注解,则创建EnumShowIntegerSerializer;
     * 如果没有相关的注解,则返回默认的整数序列化器。
     * 
     * @param serializerProvider   序列化提供者,用于获取其他序列化器。
     * @param beanProperty   当前属性的信息,用于获取注解。
     * @return 自定义的序列化器或默认的整数序列化器。
     * @throws JsonMappingException 如果创建序列化器过程中发生错误。
     */
    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        if (beanProperty != null) {
            EnumShow annotation = beanProperty.getAnnotation(EnumShow.class);
            if (annotation != null) {
                return new EnumShowIntegerSerializer(annotation);
            }
        }
        return NumberSerializer.instance;
    }

这个Java类是一个自定义的JSON序列化器,用于将Java的整数类型(Integer)序列化为JSON格式。它继承了Jackson库中的JsonSerializer类,并实现了ContextualSerializer接口。
EnumShowIntegerSerializer 类的作用是根据EnumShow注解的配置,对整数类型的枚举值进行序列化时,除了输出数值本身,还会额外输出一个带有特定suffix的字符串字段,该字段的值是根据枚举值的特定规则计算得到的。
serialize 方法用于将整数序列化为JSON。如果传入的整数或enumShow为null,则直接将整数序列化为JSON。否则,根据enumShow的配置获取枚举类,并根据枚举类的特性进行处理:
如果枚举类实现了BaseEnum接口,则通过BaseEnum.of方法获取枚举值,并获取其对应的字符串值。
如果枚举类为普通的Java枚举,则通过反射获取枚举值的键和值方法,并遍历枚举常量,找到对应整数值的枚举值,并获取其值。
createContextual 方法用于根据属性上的注解(EnumShow或DictShow)创建并返回一个适当的自定义序列化器。如果属性上有EnumShow注解,则返回一个新的EnumShowIntegerSerializer实例;如果有DictShow注解,则返回一个新的DictShowIntegerSerializer实例;否则,返回一个默认的数字序列化器NumberSerializer.instance。
这个自定义序列化器可以用于Spring Boot应用程序中,通过@JsonComponent注解将其注册为一个Jackson组件,以便在序列化过程中自动使用。
然后对所需要的属性上加上@EnumShow注解,如下图例子
微信截图_20240610205030.png
image.png
在测试输出数据后,即可输出一个与之对应字段的翻译。

标签:enumClass,自定义,enumShow,枚举,EnumShow,注解,序列化
From: https://blog.csdn.net/qq_44082755/article/details/139582056

相关文章

  • 在使用@Transactional注解声明事务时,会有以下四种情况:哪几种会失效呢 ?
    不同情形在不同类中,事务方法A调用非事务方法B,事务具有传播性,事务生效;在不同类中,非事务方法A调用事务方法B,事务生效;在同一个类中,事务方法A调用非事务方法B,事务生效;在同一个类中,非事务方法A调用事务方法B,事务失效,这是由于使用SpringAOP代理造成的,只有当事务方法被当前类以外......
  • 3_@Autowired注解失效分析
    1.Aware接口Aware接口提供了一种[内置]的注入手段,可以注入BeanFactory,ApplicationContext。内置的注入和初始化不受扩展功能的影响,总会被执行,因此Spring框架的内部类常使用它们。InitializingBean接口提供了一种[内置]的初始化手段。Aware的作用就是注入与容器相关的信......
  • 实验6 C语言结构体、枚举应用编程
    4.实验任务41#include<stdio.h>2#defineN1034typedefstruct{5charisbn[20];6charname[80];7charauthor[80];8doublesales_price;9intsales_count;10}Book;1112voidoutput(Bookx[],int);13voidsort(Bo......
  • Spring常用注解,自动扫描装配Bean
    1引入context命名空间(在Spring的配置文件中),配置文件如下:Xml代码xmlns:context="http://www.springframework.org/schema/context"http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-2.5.xsd......
  • python实现自定义线程池
    线程池ThreadPool对象的几个关键方法:get_idle_num():获得当前空闲线程的数量submit(task:callable):把一个任务(实际上就是一个函数)提交到线程池中执行.如果没有空闲线程则阻塞.wait_idle():阻塞,直到有空闲线程stop():停止线程池中的所有线程.(注意:非强制停止,......
  • 自定义类型:结构体
    目录1.结构体类型的声明1.1结构体1.1.1结构体如何声明1.1.2结构体变量的创建和初始化1.2结构的特殊声明1.3结构的自引用2.结构体内存对齐2.1对齐规则2.2为什么存在内存对齐?2.3修改默认对齐数3.结构体传参4.结构体实现位段 4.1什么是位段4.2位段的......
  • 《物料清单汇总查询》二开增加自定义字段
    业务需求增加文本,显示物料清单的替代编码。 说明BomQueryIntegration继承了BomQueryForward。具体步骤1、新建cs类BomQueryIntegrationExtend,继承BomQueryIntegration,重写获取子项信息GetBomChildData。protectedoverrideList<DynamicObject>GetBomChildData(List<Dynami......
  • 实验6 C语言结构体、枚举应用编程
    #defineN3//运行程序输入测试时,可以把这个数组改小一些输入测试#include<stdlib.h>typedefstructstudent{intid;//学号charname[20];//姓名charsubject[20];//考试科目doubleperf;//平时成绩......
  • python后端结合uniapp与uview组件tabs,实现自定义导航按钮与小标签颜色控制
    实现效果(红框内):后端api如下:@task_api.route('/user/task/states_list',methods=['POST','GET'])@visitor_token_requireddeftask_states(user):name_list=['待接单','设计中','交付中','已完成','......
  • C#自定义控件(自定义属性、自定义事件)
    1、创建类库项目在当前解决方案中添加新项目类库。注意选择“.NETFramework”创建完成后,删除默认的Class1类。2、添加项目图片在类库的debug中添加一个文件夹image,并复制项目需要的图片。3、把全部项目拖放到资源文件中选中所有图片,然后拖放到[资源],方法是右击类库项目......