Java通过注解和反射修改属性值(男、女修改为0、1)

1.最近遇到了一个需求:导入用户信息Excel,需要将属性值:男、女,存入到数据库的时候是0、1这样的code码

2.最简单的解决方式就是if-else… ,需要转code码的属性少可以使用,多的话就比较麻烦了。

3.于是就一通搜索,写出了适合自己需求一个方法

一、话不多说,看效果(后端将男转换为0)demo地址
image.png

二、解决思路

1、通过注解标注需要转换的值

2、通过反射获取注解属性值和需要转换的值

1)、maven依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.15</version>
</dependency>
<dependency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.5</version>
</dependency>

2)、编写注解

/**
 * @author tianzhuang
 * @version 1.0
 * @date 2022/1/7 22:28
 */
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
public @interface MyAnnotation {

    /**
     * 转换的值
     *
     * @return
     */
    String readConverterExp() default "";

}

3)、编写反射工具类


/**
 * @author tianzhuang
 * @version 1.0
 * @date 2022/1/11 12:17
 */
public class ChangValue {
    /**
     * 通过注解反射更新属性的值
     *
     * @param objVal
     * @throws IllegalAccessException
     */
    public static <T> void getValByClass(T objVal) throws IllegalAccessException {
        Class<? extends T> aClass = (Class<? extends T>) objVal.getClass();
        Field[] declaredFields = aClass.getDeclaredFields();
        for (int i = 0; i < declaredFields.length; i++) {
            if (declaredFields[i].isAnnotationPresent(MyAnnotation.class)) {
                MyAnnotation annotation = declaredFields[i].getAnnotation(MyAnnotation.class);
                // 获取注解中readConverterExp字符串值
                String s = annotation.readConverterExp();
                // 设置权限
                declaredFields[i].setAccessible(true);
                // 获取属性值
                Object val = declaredFields[i].get(objVal);
                if (ObjectUtil.isNotNull(val)) {
                    // 将值进行匹配,如果匹配就更新为code,不匹配还更新为原来的值进行校验
                    // 这里可以自定义不匹配的情况下制空或者其他
                    Object obj = reverseByExp(String.valueOf(val), s);
                    // 如果val不为空,更新属性值
                    declaredFields[i].set(objVal, obj);
                    Object o = declaredFields[i].get(objVal);
                }
            }
        }
    }

    /**
     * 反向解析值 0=男,1=女
     *
     * @param propertyValue 参数值
     * @param converterExp 翻译注解
     * @return 解析后值,如果存在,则返回对应的值,不存在就返回原始值
     */
    public static Object reverseByExp(String propertyValue, String converterExp)
    {
        if (StringUtils.isBlank(propertyValue)) {
            return null;
        }
        Map<String, Object> map = new HashMap<>(16);
        String[] convertSource = converterExp.split(",");
        for (String item : convertSource)
        {
            String[] itemArray = item.split("=");
            map.put(itemArray[1], itemArray[0]);
        }
        if (!map.isEmpty()) {
            if (map.containsKey(propertyValue)) {
                return map.get(propertyValue);
            }
            return propertyValue;
        }
        return propertyValue;
    }
}

4)、自定义实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class MyUser {
    /**
     * 姓名
     */
    private String name;
    /**
     * 性别
     */
    @MyAnnotation(readConverterExp = "0=男,1=女")
    private String gender;

}

5)、编写controller(这里用的springboot)


/**
 * @author tianzhuang
 * @version 1.0
 * @date 2022/1/7 22:24
 */
@RestController
@RequestMapping("test")
public class MyAnnotationController {

    @PostMapping("getName")
    public String test(@RequestBody MyUser user) {
        try {
            ChangValue.getValByClass(user);
            return "test"+ user.toString();
        } catch (Exception e) {
            return "error";
        }
    }


    @PostMapping("getName2")
    public String test(@RequestBody Student student) {
        try {
            ChangValue.getValByClass(student);
            return "test"+ student.toString();
        } catch (Exception e) {
            return "error";
        }
    }
}

6)、用postman请求:

地址:localhost:8080/test/getName2
参数:
{

"name": "zhangsan",

"gender": "女"

}

7)、解决~~~

我是Tz,想把我遇到的问题都分享给你~~~
想看更多精彩内容,请关注我的微信公众号

在这里插入图片描述

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要通过反射修改注解中的某个属性,你可以使用 `java.lang.reflect.Proxy` 类来代理注解,并在代理对象上修改属性。下面是一个示例代码: ```java import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class Main { public static void main(String[] args) throws NoSuchFieldException { // 获取字段上的注解 Field field = MyClass.class.getDeclaredField("myField"); MyAnnotation annotation = field.getAnnotation(MyAnnotation.class); // 修改注解中的属性 if (annotation != null) { System.out.println("Before modification: " + annotation.value()); MyAnnotation modifiedAnnotation = modifyAnnotationValue(annotation, "new value"); System.out.println("After modification: " + modifiedAnnotation.value()); } } public static MyAnnotation modifyAnnotationValue(MyAnnotation annotation, String newValue) { return (MyAnnotation) Proxy.newProxyInstance( annotation.getClass().getClassLoader(), new Class[] { MyAnnotation.class }, new AnnotationInvocationHandler(annotation, newValue) ); } } class AnnotationInvocationHandler implements InvocationHandler { private final MyAnnotation originalAnnotation; private final String newValue; public AnnotationInvocationHandler(MyAnnotation originalAnnotation, String newValue) { this.originalAnnotation = originalAnnotation; this.newValue = newValue; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 修改属性 if (method.getName().equals("value")) { return newValue; } // 其他方法调用保持原样 return method.invoke(originalAnnotation, args); } } @MyAnnotation("old value") class MyClass { @MyAnnotation("old value") private String myField; } @interface MyAnnotation { String value(); } ``` 在上面的例子中,我们定义了一个自定义注解 `MyAnnotation`,并将其应用到了 `MyClass` 类的字段 `myField` 上。通过反射和动态代理,我们创建了一个代理对象,该代理对象可以修改注解中的属性。 在 `modifyAnnotationValue` 方法中,我们使用 `Proxy.newProxyInstance` 方法创建了一个代理对象,该代理对象会调用 `AnnotationInvocationHandler` 的 `invoke` 方法来处理方法调用。在 `invoke` 方法中,我们判断被调用的方法是否是注解中的属性方法(这里是 `value()` 方法),如果是,则返回修改后的属性;如果不是,则保持原样调用。 请注意,这种方法需要使用动态代理,并且可能会对性能产生一定的影响。在实际开发中,请谨慎使用反射和动态代理,并考虑其他替代方案。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值