首页 > 编程语言 >Java 通过反射获取注解属性信息以及状态中字典

Java 通过反射获取注解属性信息以及状态中字典

时间:2023-12-07 14:55:58浏览次数:49  
标签:return String value Java key import 注解 public 字典

一、创建存储对象

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *  属性对象存储类*/
public class MetadataField {
    /**
     * key 对应对象中间的属性
     */
    private String key;
    /**
     * 字段标签
     */
    private String label;
    /**
     * 列表形式的字典
     */
    private List<Map<String, String>> dictionaries;

    public MetadataField(String key, String label) {
        this.key = key;
        this.label = label;
        this.dictionaries = new ArrayList<>();
    }

    public String getKey() {
        return key;
    }

    public String getLabel() {
        return label;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    public List<Map<String, String>> getDictionaries() {
        return dictionaries;
    }

    public void setDictionaries(List<Map<String, String>> dictionaries) {
        this.dictionaries = dictionaries;
    }

    // 添加一个方法,用于往 dictionaries 中添加字典项
    public void addDictionaryItem(String key, String value) {
        Map<String, String> dictionaryItem = new HashMap<>();
        dictionaryItem.put("key", key);
        dictionaryItem.put("value", value);
        this.dictionaries.add(dictionaryItem);
    }
}

 

二、工具类(通过ApiModelProperty注解获取字段属性信息)

/**
 * 对象属性封装类*/
public class ReflectionUtils {

    /**
     * 获取指定类的属性元数据列表,包括字段名称、中文标签和字典信息。
     *
     * @param clazz 要获取元数据的类
     * @param <T>   类型参数
     * @return 包含属性元数据的列表
     */
    public static <T> List<MetadataField> getField(Class<T> clazz) {
        List<MetadataField> propertyMetadataList = new ArrayList<>();
        Field[] fields = clazz.getDeclaredFields();

        // 处理字段
        for (Field field : fields) {
            ApiModelProperty annotation = field.getAnnotation(ApiModelProperty.class);
            if (annotation != null) {
                String propertyName = field.getName();
                String chineseName = annotation.value();

                // 将驼峰命名转换为下划线命名
                String underscoredName = camelToUnderscore(propertyName);
                propertyMetadataList.add(new MetadataField(underscoredName, chineseName));
            }
        }

        // 获取所有的 getter 方法
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            if (isGetter(method)) {
                try {
                    // 调用 getter 方法获取属性值
                    Object value = method.invoke(clazz.getDeclaredConstructor().newInstance());

                    // 处理返回字典的方法
                    if (value instanceof Map) {
                        Map<?, ?> dictionary = (Map<?, ?>) value;
                        // 查找对应的 MetadataField
                        MetadataField metadataField = findMetadataFieldByPropertyName(propertyMetadataList, getPropertyNameFromGetter(method));
                        if (metadataField != null) {
                            for (Map.Entry<?, ?> entry : dictionary.entrySet()) {
                                metadataField.addDictionaryItem(entry.getKey().toString(), entry.getValue().toString());
                            }
                        }
                    }
                } catch (Exception e) {
                    handleReflectionException(e);
                }
            }
        }

        return propertyMetadataList;
    }

    /**
     * 将驼峰命名转换为下划线命名。
     *
     * @param propertyName 驼峰命名的字符串
     * @return 下划线命名的字符串
     */
    private static String camelToUnderscore(String propertyName) {
        StringBuilder result = new StringBuilder();
        for (char ch : propertyName.toCharArray()) {
            if (Character.isUpperCase(ch)) {
                result.append("_").append(Character.toLowerCase(ch));
            } else {
                result.append(ch);
            }
        }
        return result.toString();
    }

    /**
     * 判断方法是否为 getter 方法。
     *
     * @param method 要检查的方法
     * @return 如果是 getter 方法则返回 true,否则返回 false
     */
    private static boolean isGetter(Method method) {
        return method.getName().startsWith("get") && method.getParameterCount() == 0;
    }

    /**
     * 从 getter 方法中获取属性名称。
     *
     * @param method getter 方法
     * @return 属性名称
     */
    private static String getPropertyNameFromGetter(Method method) {
        String methodName = method.getName();
        return methodName.substring(3, 4).toLowerCase() + methodName.substring(4);
    }

    /**
     * 根据属性名称查找对应的 MetadataField。
     *
     * @param fields       属性元数据列表
     * @param propertyName 要查找的属性名称
     * @return 匹配的 MetadataField,如果找不到则返回 null
     */
    private static MetadataField findMetadataFieldByPropertyName(List<MetadataField> fields, String propertyName) {
        for (MetadataField field : fields) {
            if (propertyName.equals(field.getKey())) {
                return field;
            }
        }
        return null;
    }

    /**
     * 处理反射异常。
     *
     * @param e 反射异常
     */
    private static void handleReflectionException(Exception e) {
        // 处理反射异常
        e.printStackTrace();
    }
}

 

三、构建 ApiModelProperty注解对象

import com.fasterxml.jackson.annotation.JsonFormat;
import com.yf.mybatis.entity.BaseEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class DeductionDTO{

 
    @ApiModelProperty("总负责人")
    private String head;

 
    /**
     * 状态(0推进中 1已停滞 2已完成)
     */
    @ApiModelProperty("状态")
    private Map<String, Integer> status;

    // 获取 status 字段的 getter 方法
    public Map<String, Integer> getStatus() {
        Map<String, Integer> statusMapping = new HashMap<>();
        statusMapping.put("推进中", 0);
        statusMapping.put("已停滞", 1);
        statusMapping.put("已完成", 2);
        return statusMapping;
    }

    /**
     * 分类(0退税 1抵扣 2退税到账)
     */
    @ApiModelProperty("分类")
    private String type;

    public Map<String, Integer> getType() {
        Map<String, Integer> statusMapping = new HashMap<>();
        statusMapping.put("退税", 0);
        statusMapping.put("抵扣", 1);
        statusMapping.put("退税到账", 2);
        return statusMapping;
    }

    @ApiModelProperty("创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
}

 

四、前端控制器调用

 

 @PostMapping("/testField")
    public R<List<MetadataField>> testField(){
        // 获取属性名和中文描述的映射
        List<MetadataField> field = ReflectionUtils.getField(DeductionDTO.class);
        return R.data(field);
    }

 

返回结果如下:

{
    "code": 0,
    "msg": "操作成功",
    "data": [
        {
            "key": "head",
            "label": "总负责人",
            "dictionaries": []
        },
        {
            "key": "type",
            "label": "分类",
            "dictionaries": [
                {
                    "value": "1",
                    "key": "抵扣"
                },
                {
                    "value": "2",
                    "key": "退税到账"
                },
                {
                    "value": "0",
                    "key": "退税"
                }
            ]
        },
        {
            "key": "status",
            "label": "状态",
            "dictionaries": [
                {
                    "value": "2",
                    "key": "已完成"
                },
                {
                    "value": "0",
                    "key": "推进中"
                },
                {
                    "value": "1",
                    "key": "已停滞"
                }
            ]
        },
        {
            "key": "create_time",
            "label": "创建时间",
            "dictionaries": []
        }
    ]
}

 

标签:return,String,value,Java,key,import,注解,public,字典
From: https://www.cnblogs.com/springclout/p/17881990.html

相关文章

  • Java逻辑运算符,短路运算
     短路运算 因为c=5,所以c<4为false,又因为逻辑与运算,只要出现一个false就会输出所以booleand=(c<4)&&(c++<4);这行代码直接会输出false,(c++<4)也不会被执行所以输出的结果为false,c=5,而不是c=6.-----------------------------------------------------------------------......
  • java 自定义查询StringBuffer Sql
    一、背景二、实现@AutowiredprivateEntityManagerentityManager;Queryquery=entityManager.createNativeQuery(sql);query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);List<Map<String,Object>>reportWaterTota=qu......
  • 【Java语言】区域医院信息系统云HIS源码
    一个好的HIS系统,要具有开放性,便于扩展升级,增加新的功能模块,支撑好医院的业务的拓展,而且可以反过来给医院赋能,最终向更多的患者提供更好地服务。新理念新技术的趋势云计算技术:云计算是一种通过网络将高弹性的共享的物理和虚拟资源,按需进行服务和管理的方式。它具有以下特点:虚拟......
  • JS(JavaScript)-函数(方法)
      1.介绍:JS中的函数是一种通过调用来完成具体业务的一段代码块。最核心的目的是将可重复执行的操作进行封装,然后供调用方无限制的调用。 基本作用: 方法(函数)是由事件驱动的或者当他被调用时被执行的可重复使用的代码块。Jav......
  • java的unsafe类和varhandle类
    1、如何从unsafe类获取对象privateUnsafe(){}@CallerSensitivepublicstaticUnsafegetUnsafe(){Class<?>caller=Reflection.getCallerClass();if(!VM.isSystemDomainLoader(caller.getClassLoader())){thrownewSecurityException("Unsafe&quo......
  • Java开发者必备:Maven简介及使用方法详解!
    今天我们来介绍一个在Java开发中非常重要的工具——Maven。如果你是一名Java开发者,那么你一定不会对Maven感到陌生。但是,对于一些新手来说,可能还不太了解Maven是什么,它有什么作用,以及如何使用它。接下来,就让我们一起来深入了解一下Maven吧!一、maven简介Maven是什么Maven是一个......
  • 高级实现Java的七大热门技术框架解析源码特性分析
    设计模式是软件开发中常用的解决方案,可以帮助我们构建灵活可扩展的应用程序。本文将深入探讨Java的七大经典设计模式,并提供相关示例代码。一、单例模式单例模式确保一个类只有一个实例,并提供全局访问点。以下是一个简单的单例模式示例代码:publicclassSingleton{privatesta......
  • Spring Boot:Java开发者的新伙伴
    SpringBoot是一款由Pivotal团队开发的开源框架,它是Spring框架的扩展,旨在简化新生成的Spring应用程序的配置和部署。SpringBoot让Spring应用的创建更容易,因为它消除了许多样板代码和配置文件的必要性。一、SpringBoot的核心概念1.自动配置SpringBoot的自动配置特性是其吸引人......
  • Windows 下部署Redis 主从模式+哨兵模式+JAVA连接方式
    原文:Windows下部署Redis主从模式+哨兵模式+JAVA连接方式_javaredis部署-CSDN博客前言之前项目需求部署redis高可用,走了很多弯路以及相关配置来回折腾浪费了很多时间,特地记录下。主从模式:实现多台redis实例进行服务运行,并且数据相互同步;哨兵模式:实现主服务器和从服务器进行监......
  • java基本数据类型
    数据类型名称位数默认值最小值最大值byte 1字节(8位) 0 -128127 short2字节(16位) 0  -3276832767 int4字节(32位) 0  -2^31 2^31-1long8字节(64位)0L  -2^632^63-1 float4字节 0.0F   double8字节 0.0   ......