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();}
作用于字段的自定义注解代码:
package com.youku.nintendo.annotation;import java.lang.annotation.*;@Inherited@Documented@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.PARAMETER,ElementType.FIELD})public @interface PermissionKey {String value();}
怎么写权限切面呢?如何获取到post请求中RequestBody中对象的一个属性值呢?
package com.youku.nintendo.aspect;import com.alibaba.fastjson.JSON;import mon.collect.Lists;import mon.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.mon.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 mons.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.ponent;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.mon.constant.ErrorCode.ERR_ACTIVITY_CONFIG_DATA_ERROR;@Aspect@Component@Order(2)@Slf4jpublic 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();}}
注意:关于 method.setAccessible(true);
target = method.invoke(target);这两句代码啥意思?
见文章:
/qq_42292373/article/details/102469975
/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) {}
那上面是post请求的获取请求参数值的方式,那get请求呢?
get请求就很简单了,使用方式如下:
@Permission(permissionItem = PermissionTypeEnum.CONFIG, parameterName = "activityCfgCode")@PostMapping("activityCfg/update/version")public RttResult<Void> updateActivityConfigVersion(@RequestParam @PermissionKey("activityCfgCode") String activityCfgCode) {}
这种是请求参数直接就是想要获取的值,
我发现前提是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;}}}
如果觉得《有属性的自定义注解 如何获取到post请求中RequestBody中对象的一个属性值?》对你有帮助,请点赞、收藏,并留下你的观点哦!