适用于一些业务需要进行参数的统一处理,然后传入到接口中进行业务处理。
实现方法:
1、自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.METHOD)
public @interface User {
String name() default "token";
}
2、定义切面
由于需要处理参数,然后将参数通过proceed()方法传入到接口中,所以使用的是@Around注解,
@Around(value = "@annotation(com.annotations.User))")
public void pointCut(ProceedingJoinPoint joinPoint) {
try {
Object[] objects = joinPoint.getArgs(); //获得参数数组,参数的顺序是方法中参数实际的顺序
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
User token = signature.getMethod().getAnnotation(User.class);
Parameter[] parameter = signature.getMethod().getParameters();//获得方法中的参数集合
if (parameter == null) {
joinPoint.proceed();
return;
}
String accessToken = HttpRequestUtils.getHeaderParam("Authorization");//从请求头中获得token信息
for (int i = 0; i < parameter.length; i++) {
Parameter p = parameter[i];
RequestParam requestParam = p.getAnnotation(RequestParam.class);//从参数的注解中获得参数名称
if (requestParam == null) {
continue;
}
String name = requestParam.value();
if (token.name().equals(name)) {//如果两个参数名称相同,则进行赋值
String gToken =业务处理,得到数据;//通过业务处理获得对应的token
objects[i] = gToken;
break;
}
}
joinPoint.proceed(objects);
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
3、 获得header中的参数
public class HttpRequestUtils<T> {
public static HttpServletRequest getServlet() {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
return request;
}
public static String getHeaderParam(String name) {
return getServlet().getHeader(name);
}
}
4、 适用的接口类型
@User
@PostMapping(value = "/test")
public RestResponse<SyncProjectRelationshipResponse> syncData(
@RequestParam(value = "token", required = false) String token,
) {
//do something
}
5、总结
在使用表单格式提交的时候,通过Method反射方法,无法获取到实际的参数字段名,获取到的是简化的arg0、arg1,所以,需要通过注解的方式,获得实际的参数名,进行参数的赋值。
实现方式还有使用 ThreadLocal的方式,在业务中获取参数数据。