• 有属性的自定义注解,如何获取到post请求中RequestBody中对象的一个属性值?


    1,写两个自定义注解,一个作用于方法的,一个作用于字段的
    作用于方法的自定义注解代码:

    package com.youku.nintendo.annotation;
    
    
    import enums.PermissionPatternEnum;
    import enums.PermissionTypeEnum;
    
    import java.lang.annotation.*;
    
    
    @Documented
    @Target(ElementType.METHOD)
    @Inherited
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Permission {
        PermissionTypeEnum permissionItem();
        PermissionPatternEnum permissionPattern() default PermissionPatternEnum.ACT_CONGIG_PERMISSION;
        String parameterName();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    作用于字段的自定义注解代码:

    package com.youku.nintendo.annotation;
    
    import java.lang.annotation.*;
    
    
    @Inherited
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.PARAMETER,ElementType.FIELD})
    public @interface PermissionKey {
    
        String value();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    怎么写权限切面呢?如何获取到post请求中RequestBody中对象的一个属性值呢?

    package com.youku.nintendo.aspect;
    
    
    import com.alibaba.fastjson.JSON;
    import com.google.common.collect.Lists;
    import com.google.common.collect.Maps;
    import com.taobao.hsf.annotation.Order;
    import com.youku.nintendo.annotation.Permission;
    import com.youku.nintendo.annotation.PermissionKey;
    import com.youku.nintendo.api.base.result.RttResult;
    import com.youku.nintendo.common.constant.ActivityCfgType;
    import com.youku.nintendo.manager.AclManager;
    import com.youku.nintendo.manager.ActivityCfgManager;
    import com.youku.nintendo.utils.MathUtil;
    import com.youku.nintendo.vo.ActivityCfgVo;
    import enums.PermissionTypeEnum;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.lang3.StringUtils;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.web.context.request.ServletRequestAttributes;
    import org.springframework.web.context.request.RequestContextHolder;
    import javax.servlet.http.HttpServletRequest;
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.lang.reflect.Parameter;
    import java.util.List;
    import java.util.Map;
    import java.util.Objects;
    
    import static com.youku.nintendo.common.constant.ErrorCode.ERR_ACTIVITY_CONFIG_DATA_ERROR;
    
    @Aspect
    @Component
    @Order(2)
    @Slf4j
    public class ACLPermission {
    
       
        @Around(value = "@annotation(permission)")
        public Object aroundHttpPermission(ProceedingJoinPoint thisJoinPoint, Permission permission) throws Throwable{
            log.info("aroundHttpPermission into: {}", JSON.toJSONString(permission));
            Object[] args = thisJoinPoint.getArgs();
            log.info("JoinPoint,args={}", JSON.toJSONString(args));
            Method method = ((MethodSignature) thisJoinPoint.getSignature()).getMethod();
            log.info("JoinPoint,method={}", JSON.toJSONString(method));
            String parameter = getParameter(permission.parameterName(),method.getParameters(),args);
            log.info("aroundHttpPermission parameter: {}", JSON.toJSONString(parameter));
            if (parameter==null){
                return thisJoinPoint.proceed();
            }
    
         
            return thisJoinPoint.proceed();
        }
    
        public String getParameter(String parameterName, Parameter[] parameters, Object[] args) throws IllegalAccessException, InvocationTargetException {
            Map<String,Object> keyAndArgMap = Maps.newHashMap();
            for (int i = 0; i < parameters.length; i++) {
                PermissionKey permissionKey = parameters[i].getAnnotation(PermissionKey.class);
                if (Objects.nonNull(permissionKey)){
                    keyAndArgMap.put(permissionKey.value(),args[i]);
                }
            }
                if (parameterName.startsWith("${") && parameterName.endsWith("}")){
                    String realKey = parse(parameterName, keyAndArgMap);
                    if (StringUtils.isNotBlank(realKey)){
                       return realKey;
                    }
                }else {
                    Object arg = keyAndArgMap.get(parameterName);
                    if (Objects.isNull(arg)){
    
                    }
                    return String.valueOf(arg);
                }
                return null;
        }
    
        /**
         * 解析 目前只简单解析"."符号
         * @param key
         * @param keyAndArgMap
         * @return
         * @throws IllegalAccessException
         */
        private String parse(String key, Map<String,Object> keyAndArgMap) throws IllegalAccessException, InvocationTargetException {
            int index = key.indexOf("${");
            int lastIndex = key.lastIndexOf("}");
            String realKey = key.substring(index + 2, lastIndex);
            String[] split = realKey.split("\\.");
            Object target = keyAndArgMap.get(split[0]);
            if (Objects.isNull(target)){
                //配置有误
            }
            for (int i = 1; i <split.length; i++) {
                Method[] methods = target.getClass().getMethods();
                boolean find = false;
                for (Method method : methods) {
                    String name = method.getName();
                    String upperCaseFirst = buildGetMethodName(split[i]);
                    if (name.equals(upperCaseFirst)){
                        method.setAccessible(true);
                        target = method.invoke(target);
                        find = true;
                    }
                }
                if (!find){
                    //如果没有匹配到真实值,说明配置有误
                }
            }
            return String.valueOf(target);
        }
    
        private String buildGetMethodName(String str){
            char upperCase = Character.toUpperCase(str.charAt(0));
            StringBuilder builder = new StringBuilder(str.length());
            builder.append("get");
            builder.append(upperCase);
            for (int i = 1; i < str.length(); i++) {
                builder.append(str.charAt(i));
            }
            return builder.toString();
        }
    
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134

    注意:关于 method.setAccessible(true);
    target = method.invoke(target);这两句代码啥意思?
    见文章:
    https://blog.csdn.net/qq_42292373/article/details/102469975
    http://www.wityx.com/post/22598_1_1.html

    如何使用这个自定义注解?

    
        @Permission(permissionItem = PermissionTypeEnum.CONFIG, parameterName = "${acfg.activityCfgCode}")
        **@PostMapping**("activityCfg/update/white/user")
        public RttResult<Void> updateActivityConfigWhiteUser(@RequestBody @PermissionKey("acfg") ActivityCfgUpdateRequest activityCfgUpdateRequest) {
        }
       
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    那上面是post请求的获取请求参数值的方式,那get请求呢?

    get请求就很简单了,使用方式如下:

     @Permission(permissionItem = PermissionTypeEnum.CONFIG, parameterName = "activityCfgCode")
        @PostMapping("activityCfg/update/version")
        public RttResult<Void> updateActivityConfigVersion(@RequestParam @PermissionKey("activityCfgCode") String activityCfgCode) {
        }
    
    • 1
    • 2
    • 3
    • 4

    这种是请求参数直接就是想要获取的值,
    我发现前提是get请求,如果请求参数在request中,此时也能直接在自定义注解中的属性中获取到request中的某一参数值。
    示例如下代码中的idParameterName = “act_id”

     @Permission(permissionItem = PermissionItemEnum.ACTIVITY, permissionPattern = PermissionPatternEnum.LINE_PERMISSION, idParameterName = **"act_id"**)
        @ResponseBody
        @RequestMapping(value = "/visualOptimization", method = RequestMethod.GET)
        public ResultDTO visualOptimization(HttpServletRequest request) {
          Map<String, String[]> parameterMap = new HashMap<String, String[]>(r**equest.getParameterMap());**
            Set<String> keys = parameterMap.keySet();
            int size = keys.size();
            int k = 0;
            for (String pkey : keys) {
                k++;
                String[] b = parameterMap.get(pkey);
                url += pkey + "=";
                if (b != null && b.length != 0) {
                    String value = null;
                    try {
                        value = URLEncoder.encode(b[0], "UTF-8");
    
                        //替换活动id
                        **if ("act_id".equals(pkey)) {**
                            HollywoodActivityDO activityDO = activityService.queryById(Long.parseLong(value));
                            value = activityDO.getActivityId();
                        }
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                    if (k != size) {
                        url += value + "&";
                    } else {
                        url += value;
                    }
                }
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
  • 相关阅读:
    如何使用IntelliJ IDEA将普通项目转换为Maven项目
    Programming Differential Privacy第九章
    76~90(正则表达式)
    形式化验证方法研究综述
    【论文笔记】Transformers in Remote Sensing: A Survey 中的相关论文链接
    第一:Python基于钉钉监控发送消息提醒
    论文阅读之RETHINKING POSITIONAL ENCODING IN LANGUAGE PRE-TRAINING
    Spring事务之@Transactional注解详解
    TP5 封装通用的微信服务类
    断言(assert)的用法
  • 原文地址:https://blog.csdn.net/weixin_43228497/article/details/126056996