java 注解实现实体字段翻译(数据字典、枚举、数据库...)

注解以及基础类说明

实体注解:Translate

将注解标记在翻译结果存取字段,eg:需将commodityCode翻译结果赋值到commodityName字段上,则在commodityName加注解,指定需要翻译的字段名.不指定默认需要翻译的字段为本字段并且翻译结果覆盖本字段。

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Translate {
    // 需要翻译的字段名称
    String code() default "";

    // 日期格式
    String datePartten() default DateUtilConstant.NORM_DATETIME_PATTERN;

    /**
     * 数据字典类型(对应dictionary表code字段,多个以英文状态下的逗号分割,数据字典翻译必传!!!)
     *
     * @return
     */
    String[] dictionaryType() default "";

    /**
     * 是否批量翻译字符串,多个值用英文状态下逗号","进行分割 如 1,2,3
     *
     * @return
     */
    boolean whetherStr() default false;

    /**
     * 需要翻译的枚举信息,需implements EnumUtils.IEnum
     * {@link com.ltd.cloud.meteorological.common.utils.EnumUtils}
     *
     * @return
     */
    Class EnumClaz() default Void.class;

    /**
     * 翻译类型
     * {@link com.ltd.cloud.meteorological.biz.translate.constant.TranslateConstant}
     *
     * @return
     */
    int type();
}

Type常量类:TranslateConstant

public class TranslateConstant {
    private TranslateConstant() {
    }

    /**
     * 用户单位(key:用户单位id,value:用户单位名称)
     */
    public static final int USER_UNIT = 1;
    /**
     * 枚举(需实现EnumUtils.IEnum<C, M>)
     */
    public static final int ENUM_CLAZ = 2;
    /**
     * 数据字典(key:数据字典value,value:数据字典dict_desc)
     */
    public static final int DICTION = 3;

    /**
     * 日期(指定格式常量类:DateUtilConstant)
     */
    public static final int DATE = 4;

    /**
     * 地区
     */
    public static final int DIVISION = 5;

}


枚举工具类:EnumUtils

public class EnumUtils {

    /**
     * 根据code获取枚举类的值
     * @param enumType 枚举类
     * @param code 枚举值
     * @param <C> 枚举值类
     * @param <T> 对应值类
     * @return 返回整个枚举
     */
    public static <C, T extends IEnum<Integer, String>> T getEnumValue(Class<T> enumType, C code) {
        try {
            //如果是枚举类型 则调用values方法
            if (enumType.isEnum()) {
                Method values = enumType.getDeclaredMethod("values");
                T[] ts = (T[]) values.invoke(null);
                for (T t : ts) {
                    if (code.equals(t.getCode())) {
                        return t;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据code获取枚举Code
     *
     * @param enumType 枚举类型
     * @param code 枚举值
     * @param <C> 编码类
     * @param <T> 对应值类
     * @return 对应值
     */
    public static <C, T extends IEnum<Object, String>> String getMessageByCode(Class<T> enumType, C code) {
        try {
            if (enumType.isEnum()) {
                Method m = enumType.getDeclaredMethod("values");
                T[] ts = (T[]) m.invoke(null);
                for (T t : ts) {
                    if (code.equals(t.getCode())) {
                        return t.getMessage();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";

    }

    public interface IEnum<C, M> { //如果是成员方法共通,可以抽象为接口或把属性也加上变为抽象类,这里以接口为例子
        /**
         * 获取枚举值
         * @return 枚举值
         */
        C getCode();

        /**
         * 获取对应值
         * @return 对应值
         */
        M getMessage();
    }
}

基础实体:TranslateEntity

@Data
@ApiModel("翻译实体")
public class TranslateEntity {
        @ApiModelProperty("翻译类型")
    private Integer translateType;

    @ApiModelProperty("翻译字段,key-需要翻译的字段 value-接收翻译值字段")
    private Pair<String, String> pair;

    @ApiModelProperty("数据字典类型(对应dictionary表code字段)")
    private String[] dictionaryType;

    @ApiModelProperty("枚举类")
    private Class enumClass;

    @ApiModelProperty("翻译字段信息")
    private Field field;

    @ApiModelProperty("翻译结果字段信息")
    private Field translateField;

    @ApiModelProperty("是否批量翻译字符串")
    private Boolean whetherStr;

    @ApiModelProperty("日期格式")
    private String datePartten;
}

翻译对象实体:TranslateObjectEntity

@Data
@ApiModel("翻译对象实体")
public class TranslateObjectEntity {
       @ApiModelProperty("翻译信息实体")
    private List<TranslateEntity> translateInfo;

    @ApiModelProperty("对象信息")
    private Class<?> aClass;

    @ApiModelProperty("部门信息")
    private Map<Long, String> userUnits;

    @ApiModelProperty("字典信息(Map<code_value,dictDesc>)")
    private Map<String, String> dictions;
}

翻译工具类:TranslateUtils

@Slf4j
public class TranslateUtils {

    private static UserUnitService userUnitService = SpringContextHolder.getBean(UserUnitService.class);
    private static DivisionService divisionService = SpringContextHolder.getBean(DivisionService.class);


    /**
     * 根据code翻译字段名称
     *
     * @param list 需要翻译的集合
     */
    public static <T> void translateList(List<T> list) {
        if (CollectionUtil.isEmpty(list)) {
            return;
        }
        TranslateObjectEntity info = getObjectInfo(list.get(0));
        if (ObjectUtil.isEmpty(info)) {
            return;
        }
        for (T obj : list) {
            translateObject(obj, info);
        }
    }

    /**
     * 根据code翻译字段名称(转化为指定实体集合)
     *
     * @param list 需要翻译的集合
     */
    public static <T, R> List<R> translateList(List<T> list, Class<R> targetClazz) {
        List<R> targrts = new ArrayList<>();
        if (CollectionUtil.isEmpty(list)) {
            return targrts;
        }
        TranslateObjectEntity info = null;
        for (T obj : list) {
            R targetObj = BeanUtil.copyProperties(obj, targetClazz);
            if (ObjectUtil.isEmpty(info)) {
                info = getObjectInfo(targetObj);
            }
            translateObject(targetObj, info);
            targrts.add(targetObj);
        }
        return targrts;
    }


    /**
     * 翻译单个实体
     *
     * @param obj 实体信息
     * @param <T>
     */
    public static <T> void translateObject(T obj) {
        if (ObjectUtil.isEmpty(obj)) {
            return;
        }
        TranslateObjectEntity info = getObjectInfo(obj);
        if (ObjectUtil.isEmpty(info)) {
            return;
        }
        translateObject(obj, info);
    }

    /**
     * 翻译单个实体
     *
     * @param obj         实体信息
     * @param targetClazz 需返回的实体class
     * @param <T>         原实体
     * @param <R>         返回实体
     * @return
     */
    public static <T, R> R translateObject(T obj, Class<R> targetClazz) {
        if (ObjectUtil.isEmpty(obj) || ObjectUtil.isEmpty(targetClazz)) {
            return null;
        }
        R properties = BeanUtil.copyProperties(obj, targetClazz);
        TranslateObjectEntity info = getObjectInfo(properties);
        if (ObjectUtil.isEmpty(info)) {
            return null;
        }
        translateObject(properties, info);
        return properties;
    }


    /**
     * 翻译单个对象(获取需要翻译的对象实体信息)
     *
     * @param obj 对象信息
     * @param <T> 对象字段翻译信息
     */
    private static <T> TranslateObjectEntity getObjectInfo(T obj) {
        if (ObjectUtil.isEmpty(obj)) {
            return null;
        }
        Class<?> aClass = obj.getClass();
        TranslateObjectEntity objectEntity = new TranslateObjectEntity();
        objectEntity.setAClass(aClass);
        Map<String, Field> fields = getAllFileds(aClass);

        List<TranslateEntity> translateInfo = new ArrayList<>();
        TranslateEntity translateEntity = null;
        Pair<String, String> pair = null;
        // 用户单位
        Map<Long, String> userUnits = null;
        // 数据字典
        Map<String, String> dictions = null;

        List<String> dictionsCodes = new ArrayList<>();
        for (Field field : fields.values()) {
            if (field.isAnnotationPresent(Translate.class)) {
                translateEntity = new TranslateEntity();
                translateEntity.setTranslateField(field);
                Translate annotation = field.getAnnotation(Translate.class);
                String translateCode = annotation.code();
                if (StringUtils.isBlank(translateCode)) {
                    translateCode = field.getName();
                }
                translateEntity.setField(fields.get(translateCode));
                int translateType = annotation.type();
                pair = Pair.of(translateCode, field.getName());
                translateEntity.setTranslateType(translateType);
                translateEntity.setPair(pair);
                if (TranslateConstant.ENUM_CLAZ == translateType) {
                    translateEntity.setEnumClass(annotation.EnumClaz());
                }
                if (TranslateConstant.USER_UNIT == translateType && CollUtil.isEmpty(userUnits)) {
                    userUnits = getUserUnits();
                }
                if (TranslateConstant.DICTION == translateType && CollUtil.isEmpty(dictions)) {
                    String[] dictionaryType = annotation.dictionaryType();
                    List<String> strings = Arrays.asList(dictionaryType);
                    if (CollUtil.isEmpty(strings)) {
                        Asserts.fail("数据字典类型不能为空");
                    }
                    dictionsCodes.addAll(strings);
                    translateEntity.setDictionaryType(annotation.dictionaryType());
                }
                if (TranslateConstant.DATE == translateType) {
                    translateEntity.setDatePartten(annotation.datePartten());
                }
                translateEntity.setWhetherStr(annotation.whetherStr());
                translateInfo.add(translateEntity);
            }
        }
        dictions = getDictions(dictionsCodes);
        objectEntity.setUserUnits(userUnits);
        objectEntity.setDictions(dictions);
        objectEntity.setTranslateInfo(translateInfo);
        return objectEntity;
    }


    /**
     * 获取所有字段含父级
     *
     * @param aClass 实体类
     * @return 所有字段信息
     */
    private static Map<String, Field> getAllFileds(Class<?> aClass) {
        Map<String, Field> fileds = new HashMap<>();
        List<Field> fieldList = new ArrayList<>();
        Class tempClass = aClass;
        //当父类为null的时候说明到达了最上层的父类(Object类).
        while (tempClass != null) {
            fieldList.addAll(Arrays.asList(tempClass.getDeclaredFields()));
            tempClass = tempClass.getSuperclass(); //得到父类,然后赋给自己
        }
        for (Field field : fieldList) {
            fileds.put(field.getName(), field);
        }
        return fileds;
    }


    /**
     * 翻译单个实体
     *
     * @param obj  实体信息
     * @param info 翻译对象信息
     * @param <T>
     */
    private static <T> void translateObject(T obj, TranslateObjectEntity info) {
        try {
            // 地区信息集合
            Map<String, String> areasInfo = new HashMap<>();
            for (TranslateEntity entity : info.getTranslateInfo()) {
                Integer type = entity.getTranslateType();
                Field field = entity.getField();
                field.setAccessible(true);

                Object codeInfo = field.get(obj);
                Field translate = entity.getTranslateField();
                translate.setAccessible(true);
                if (null == codeInfo) {
                    continue;
                }
                Object value = null;
                String key = codeInfo.toString();

                switch (type) {
                    case TranslateConstant.USER_UNIT:
                        // 用户单位
                        if (info.getUserUnits().containsKey(Long.parseLong(key))) {
                            value = info.getUserUnits().get(Long.parseLong(key));
                        }
                        break;
                    case TranslateConstant.ENUM_CLAZ:
                        // 枚举
                        Class enumClass = entity.getEnumClass();
                        value = EnumUtils.getMessageByCode(enumClass, codeInfo);
                        break;
                    case TranslateConstant.DICTION:
                        String[] types = entity.getDictionaryType();
                        if (entity.getWhetherStr()) {
                            String[] split = key.split(",");
                            List<String> values = new ArrayList<>();
                            for (String str : split) {
                                String result = null;
                                for (String s : types) {
                                    String strs = s + CommonSymbolConstant.UNDERLINE + str;
                                    if (StringUtils.isBlank(result) && info.getDictions().containsKey(strs)) {
                                        result = info.getDictions().get(strs);
                                        values.add(result);
                                        break;
                                    }
                                }

                            }
                            value = StringUtils.join(values, ",");
                        } else {
                            for (String s : types) {
                                String mapKey = s + CommonSymbolConstant.UNDERLINE + key;
                                // 数据字典
                                if (info.getDictions().containsKey(mapKey)) {
                                    value = info.getDictions().get(mapKey);
                                    break;
                                }
                            }
                        }
                        break;
                    case TranslateConstant.DATE:
                        Class<?> aClass = codeInfo.getClass();
                        if (aClass == LocalDateTime.class) {
                            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(entity.getDatePartten());
                            value = ((LocalDateTime) codeInfo).format(dateTimeFormatter);
                        }
                        break;
                    case TranslateConstant.DIVISION:
                        if (areasInfo.containsKey(key)) {
                            value = areasInfo.get(key);
                        } else {
                            value = getAreaNameById(key);
                        }
                        break;
                    default:
                        break;
                }
                translate.set(obj, value);
            }
        } catch (Exception e) {
            log.error("翻译失败:{}", e);
        }
    }

    /**
     * 根据地区id获取地区名字
     *
     * @param areaId 地区id
     * @return 地区名字
     */
    private static String getAreaNameById(String areaId) {
        String name = null;
        try {
            DivisionDTO divisionDTO = divisionService.getDivisionById(Long.valueOf(areaId));
            if (ObjectUtil.isNotEmpty(divisionDTO)) {
                name = divisionDTO.getName();
            }
        } catch (Exception e) {
            log.error("获取地区名字失败:{}", e.getMessage());
        }
        return name;
    }

    /**
     * 获取所有用户单位信息
     *
     * @return 用户单位信息
     */
    private static Map<Long, String> getUserUnits() {
        Map<Long, String> map = new HashMap<>();
        try {
            List<UserUnitDto> dtos = userUnitService.list(null);
            for (UserUnitDto Dto : dtos) {
                map.put(Dto.getId(), Dto.getName());
            }
        } catch (Exception e) {
            log.error("用户单位信息获取失败:{}", e.getMessage());
        }
        return map;
    }

    /**
     * 获取数据字典集合
     *
     * @param codes 数据字典code
     * @return 数据字典集合
     */
    private static Map<String, String> getDictions(List<String> codes) {
        Map<String, String> diction = new HashMap<>();
        try {
            List<DictionaryDO> list = DictionaryUtils.getDictListByCodes(codes);
            for (DictionaryDO dictionaryDO : list) {
                diction.put(dictionaryDO.getCode() + CommonSymbolConstant.UNDERLINE + dictionaryDO.getValue(), dictionaryDO.getDictDesc());
            }
        } catch (Exception e) {
            log.error("数据字典查询失败:{}", e.getMessage());
        }
        return diction;
    }

}


使用举例

实体使用

@Data
@ApiModel("品种信息实体")
public class CommodityDTO {

     @ApiModelProperty(value = "所属类型数据字典code:RISK_DATA_TYPE;风险评估专题库、气象灾害指数专题库")
    private String belongTypeCode;

    @ApiModelProperty(value = "所属类型名称")
    @Translate(code = "belongTypeCode", type = TranslateConstant.DICTION, dictionaryType = DictionaryCodeConstant.RISK_DATA_TYPE)
    private String belongTypeName;
    
    @ApiModelProperty(value = "是否预测数据(数据类型) 0-否 1-是")
    private Integer whetherForecast;

    @ApiModelProperty(value = "是否预测数据(数据类型) ")
    @Translate(code = "whetherForecast", type = TranslateConstant.ENUM_CLAZ, EnumClaz = WhetherForecastEnum.class)
    private String whetherForecastName;
    
  	@ApiModelProperty(value = "评估时间")
    @ExcelIgnore
    private LocalDateTime evaluationTime;

    @ApiModelProperty(value = "评估时间")
    @ExcelProperty("评估时间")
    @Translate(code = "evaluationTime", type = TranslateConstant.DATE)
    private String evaluationTimeStr;

}

方法调用

TranslateUtils.translateList(list);
  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
### 回答1: 实现步骤如下: 1. 先定义一个注解类 @Excel,用来标识实体类中的字段。 2. 在实体类中的字段上使用 @Excel 注解,并为其设置中文名称。 3. 使用 Java 反射机制,遍历实体类中的字段,获取 @Excel 注解,从而得到字段的中文名称。 代码示例: ``` import java.lang.reflect.Field; public class ExcelUtils { public static String getExcelHeader(Class clazz) { Field[] fields = clazz.getDeclaredFields(); StringBuilder header = new StringBuilder(); for (Field field : fields) { Excel excel = field.getAnnotation(Excel.class); if (excel != null) { header.append(excel.name()).append(","); } } header.deleteCharAt(header.length() - 1); return header.toString(); } } ``` 使用方法: ``` String header = ExcelUtils.getExcelHeader(YourEntityClass.class); System.out.println(header); ``` ### 回答2: 在Java中使用反射机制可以实现获取实体类中有@Excel注解字段的中文值。 首先,我们需要定义一个方法,该方法接受一个实体类对象作为参数,并返回一个Map,其中key为字段名,value为字段的中文名。 在方法中,我们先通过Class对象的getDeclaredFields()方法获取实体类中的所有字段。然后遍历字段数组,对于每个字段,我们判断是否存在@Excel注解,如果存在,则获取注解的值,并将字段名和注解的值以键值对的形式存入Map中。最后返回该Map即可。 具体代码实现如下所示: ```java import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; public class ExcelUtils { public static Map<String, String> getExcelFieldMap(Object entity) { Map<String, String> excelFieldMap = new HashMap<>(); // 获取实体类的Class对象 Class<?> clazz = entity.getClass(); // 获取实体类中所有的字段 Field[] fields = clazz.getDeclaredFields(); // 遍历字段数组 for (Field field : fields) { // 判断字段上是否存在@Excel注解 if (field.isAnnotationPresent(Excel.class)) { // 获取字段上的@Excel注解 Excel excelAnnotation = field.getAnnotation(Excel.class); // 获取@Excel注解的值,即字段的中文名 String excelFieldName = excelAnnotation.value(); // 将字段名和中文名以键值对的形式存入Map中 excelFieldMap.put(field.getName(), excelFieldName); } } return excelFieldMap; } } ``` 使用该方法时,只需传入实体类对象,即可获取实体类中有@Excel注解字段的中文名。示例如下: ```java public class Main { public static void main(String[] args) { User user = new User(); Map<String, String> excelFieldMap = ExcelUtils.getExcelFieldMap(user); System.out.println(excelFieldMap); } } ``` 以上就是使用Java实现获取实体类中有@Excel注解字段中文名的方法。 ### 回答3: 在Java实现获取实体类中带有@Excel注解字段的中文信息,我们可以通过反射的方式来实现。 首先,我们需要定义一个注解处理器,用于解析实体类中的@Excel注解,并获取其中文信息。该注解处理器可以使用Java反射机制,通过获取类的字段注解的方式来实现。 具体实现步骤如下: 1. 定义一个注解类@Excel,其中包含一个value属性,用于表示字段的中文信息。 ```java @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Excel { String value(); } ``` 2. 在实体类中,为需要获取中文信息的字段添加@Excel注解,并设置对应的中文信息。 ```java public class Entity { @Excel("姓名") private String name; @Excel("年龄") private int age; // 省略其他字段及其对应的setter和getter方法 } ``` 3. 创建一个工具类,用于解析实体类中的@Excel注解,并获取其中文信息。 ```java public class ExcelUtil { public static Map<String, String> getExcelFieldMap(Class clazz) { Map<String, String> excelFieldMap = new HashMap<>(); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { Excel excelAnnotation = field.getAnnotation(Excel.class); if (excelAnnotation != null) { excelFieldMap.put(field.getName(), excelAnnotation.value()); } } return excelFieldMap; } } ``` 4. 在其他类中,调用ExcelUtil工具类的getExcelFieldMap方法,传入实体类的Class对象,即可获取实体类中带有@Excel注解字段的中文信息。 ```java public class Main { public static void main(String[] args) { Map<String, String> excelFieldMap = ExcelUtil.getExcelFieldMap(Entity.class); System.out.println(excelFieldMap); } } ``` 通过以上步骤,我们可以获取实体类中带有@Excel注解字段的中文信息。输出结果如下: ``` {age=年龄, name=姓名} ``` 这就是通过Java实现获取实体类中带有@Excel注解字段中文的方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值