Java利用注解反射取值

该文描述了一个Java系统中,使用注解处理工作订单字段的机制。注解`FieldKey`用于标记实体类的字段,实体类`VehicleAnnualReviewWorkOrderVo`包含了这些注解。`WorkOrderFieldConvert`类负责根据注解从工作订单字段列表中提取并转换值,利用反射设置到实体对象中。文章还展示了如何调用这个转换功能来获取工作订单的所有字段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、注解类

package com.dst.common.entities.workorder.workorderfield.annotation;

import java.lang.annotation.*;

/**
 * @Author liuweiping
 * @Date 2023/2/20 13:51
 * @Description:工单字段注解
 **/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FieldKey {

    /**
     * 字段key
     * @return
     */
    String value();

    /**
     * 数组值类型取值下标
     * @return
     */
    int index() default -1;
}

二、注解上的实体类

package com.dst.common.entities.workorder.annualreview;

import com.dst.common.entities.workorder.workorderfield.annotation.FieldKey;
import lombok.Data;

import java.util.Date;
import java.util.List;

/**
 * @Author liuweiping
 * @Date 2023/2/20 11:25
 * @Description:
 **/
@Data
public class VehicleAnnualReviewWorkOrderVo {

    /**
     * 执行场站
     */
    @FieldKey(value = "station_1676432469000_18165",index = 0)
    private String station;

    /**
     * 年审车架号
     */
    @FieldKey(value = "carNoAndVinCode_1676432840000_22149",index = 0)
    private String vinCode;

    /**
     * 年审预警单号
     */
    @FieldKey(value = "input_1676432885000_17230")
    private String warningCode;

    /**
     * 期望完成时间
     */
    @FieldKey(value = "date_1676445725000_28602",index = 0)
    private String ExpectedCompletionTime;

    /**
     * 送审日期 yyyy-MM-dd
     */
    @FieldKey(value = "date_1676432936000_30427",index = 0)
    private String submissionDate;

    /**
     * 年审地址
     */
    @FieldKey(value = "input_1676432967000_87359")
    private String annualReviewAddr;

    /**
     * 在检验站的车辆照片
     */
    @FieldKey(value = "pictureUpload_1676432985000_9206")
    private List<String> checkpointPhotos;

    /**
     * 实际审验日期   yyyy-MM-dd
     */
    @FieldKey(value = "date_1676433066000_91981",index = 0)
    private String actualAuditDate;

    /**
     * 检验有效期至   yyyy-MM-dd
     */
    @FieldKey(value = "date_1676433154000_73426",index = 0)
    private String checkExpirationTime;

    /**
     * 行驶证照片
     */
    @FieldKey(value = "pictureUpload_1676433171000_73227")
    private List<String> travelPhotos;

    /**
     * 车辆开回日期   yyyy-MM-dd
     */
    @FieldKey(value = "date_1676433215000_12781",index = 0)
    private String returnDate;

    /**
     * 在场站的车辆照片 yyyy-MM-dd
     */
    @FieldKey(value = "pictureUpload_1676433259000_8042")
    private List<String> stationPhotos;

}

三、根据注解取值转换类

package com.dst.common.convert;

import com.alibaba.fastjson.JSONObject;
import com.dst.common.entities.workorder.workorderfield.annotation.FieldKey;
import com.dst.modules.business.workorder.workorderbase.service.fieldType.FieldTypeMap;
import com.dst.modules.business.workorder.workorderbase.service.fieldType.WorkOrderFieldType;
import com.dstcar.common.global.GlobalException;
import com.dstcar.common.utils.json.JsonUtil;
import com.dstcar.entitys.workorderbase.WorkOrderProcessField;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author liuweipng
 * @Date 2023/2/20 14:10
 * @Description: 工单字段值映射类
 **/
@Component
public class WorkOrderFieldConvert {
    //传入的泛型是要设置的值,第二个参数是要取值的表单字段对象
    public <T> void convert(T objectClazz, List<WorkOrderProcessField> workOrderAllFeild){
        Map<String, WorkOrderProcessField> workOrderProcessFieldMap = workOrderAllFeild.stream().collect(Collectors.toMap(WorkOrderProcessField::getFieldKey, Function.identity(), (k1, k2) -> k2));
        Class<?> clazz = objectClazz.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            FieldKey fieldKey = field.getDeclaredAnnotation(FieldKey.class);
            if(fieldKey != null){
                String v = fieldKey.value();
                field.setAccessible(true);
                WorkOrderProcessField workOrderProcessField = workOrderProcessFieldMap.get(v);
                if(workOrderProcessField.getValueType() == 1){
                    //利用反射设置值
                    ReflectionUtils.setField(field, objectClazz, parseString(workOrderProcessField.getValue(),v));
                }else{
                    if(workOrderProcessField.getValue() == null) return ;
                    List<String> values = parseList(workOrderProcessField.getValue(), v);
                    if(fieldKey.index()<0){
                        ReflectionUtils.setField(field, objectClazz,values);
                    }else{
                        ReflectionUtils.setField(field, objectClazz, values.get(fieldKey.index()));
                    }

                }

            }
        }

    }

    //解析字符串类型
    String parseString(String o,String fieldKey){
        try {
            return JSONObject.parseObject(o,String.class);
        }catch (Exception e){
            throw new GlobalException(String.format("%s字段值解析异常",fieldKey));
        }
    }

    //解析数组类型
    List<String> parseList(String o,String fieldKey){
        try {
            return JSONObject.parseArray(o, String.class);
        }catch (Exception e){
            throw new GlobalException(String.format("%s字段值解析异常",fieldKey));
        }
    }

}
   //调用方转换取值入口
    public VehicleAnnualReviewWorkOrderVo getWorkOrderAllFeild(String workOrderCode) {
        VehicleAnnualReviewWorkOrderVo vehicleAnnualReviewWorkOrderVo = new VehicleAnnualReviewWorkOrderVo();
        List<WorkOrderProcessField> workOrderAllFeild = workOrderBaseInfoService.getWorkOrderAllFeild(workOrderCode);
        workOrderFieldConvert.convert(vehicleAnnualReviewWorkOrderVo,workOrderAllFeild);
        return vehicleAnnualReviewWorkOrderVo;
    }

四、取值效果如图

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值