Springboot⾃定义注解+AOP实现参数不能为空⾃定义注解类
package dular.system.util.annotation;
import java.lang.annotation.*;
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CheckNullParams {
String[] params();
}
AOP
package dular.system.util.aspect;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import ption.ServiceException;
import dular.system.util.annotation.CheckNullParams;
slf4j.Slf4j;
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.flect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.t.request.RequestContextHolder;
import org.t.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
/**
* 校验参数不能为空
* ProceedingJoinPoint只能⽤在环绕通知上。
*/
@Slf4j
@Aspect
@Component
public class CheckNullParamsAspect {
private static String dateFormat = "yyyy-MM-dd HH:mm:ss";
@Pointcut("@annotation(dular.system.util.annotation.CheckNullParams)")
public void paramNotNull(){}
@Around("paramNotNull()")
public Object  doAround(ProceedingJoinPoint joinPoint) throws Throwable{
log.info("进⼊到环绕通知中");
// 1、记录⽅法开始执⾏的时间
long start = System.currentTimeMillis();
/
/ 2、打印请求参数
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestAttributes();
HttpServletRequest request = Request();
String target = Signature().getDeclaringTypeName();              // 全路径类名
String classNm = target.substring(target.lastIndexOf(".") + 1, target.length()); // 类名截取
String method = Signature().getName();                          // 获取⽅法名
Map<String, String> params = getAllRequestParam(request);                    // 获取请求参数
log.info("{}.{} 接收参数: {}", classNm, method, JSONString(params));
CheckNullParams check = ((MethodSignature) Signature()).getMethod().getAnnotation(CheckNullParams.class); // 获取注解        String[] requiredFields = check.params();                                  // 获取注解参数
/
/ 3、必填参数⾮空校验
Map<String,Object> result = validParams(params, requiredFields);
if ((Boolean) ("boolean")) {
Object object = joinPoint.proceed();        // 必填参数⾮空校验通过,执⾏⽅法,获取执⾏结果
// 4、打印应答数据和⽅法耗时
long time = System.currentTimeMillis() - start;
log.info("{}.{} 应答数据: {}; 耗时 {} ms", classNm, method, JSONStringWithDateFormat(object,
dateFormat, SerializerFeature.WriteMapNullValue), time);
return object;
} else {
/
/ 必填参数⾮空校验未通过,抛出异常,由GlobalExceptionHandler捕获全局异常,返回调⽤⽅“参数缺失”
throw new ServiceException(500, "参数【" + ("param") + "】缺失或格式错误");
}
}
/**
* 校验传⼊参数params(⾮null)中是否必含requiredFields(⾮null)中的各个属性,且属性值⾮空
*
* @param params        传⼊参数
* @param requiredFields 设置的⾮空属性数组
* @return 校验通过返回true,否则返回false
*/
private Map<String,Object> validParams(Map<String, String> params, String[] requiredFields) {
Map<String, Object> map = new HashMap<>(2);
if (requiredFields.length == 0) {
// ⽆必送参数,直接返回true
map.put("boolean", true);
return map;
} else {
for (String field : requiredFields) {
if (StringUtils.(field))) {
map.put("boolean", false);
map.put("param", field);
return map;
}
}
map.put("boolean", true);
return map;
}
}
/**
* 获取请求参数
*/
public static Map<String, String> getAllRequestParam(HttpServletRequest request) {
Map<String, String> res = new HashMap<>();
Enumeration<?> temp = ParameterNames();
if (null != temp) {
while (temp.hasMoreElements()) {
String en = (String) Element();
String value = Parameter(en);
res.put(en, value);
// 在报⽂上送时,如果字段的值为空,则不上送<;下⾯的处理为在获取所有参数数据时,判断若值为空,则删除这个字段>
if (StringUtils.(en))) {
}
}
}
return res;
}
}
扩展
上⾯是AOP实现的业务逻辑,有的时候需要通过反射去处理 ,⽐如通过⽅法来获取⽅法上的注解信息以及注解⾥⾯的值等java 获取类,属性变量,⽅法,⽅法参数上注解的值等
获取类上注解的值
定义注解@Target(ElementType.TYPE)⽤于类,接⼝等
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Orange {
String getName();
String getValue();
}
获取
@Orange(getName = "3333",getValue = "4444")
public class ParameterNameTest {
。。。
@Test
public void main() throws Exception {
Class<ParameterNameTest> clazz = ParameterNameTest.class;
if(clazz.isAnnotationPresent(Orange.class)){
// 获取 "类" 上的注解
Orange getAnnotation = Annotation(Orange.class);
System.out.println("\"类\"上的注解值获取到第⼀个:"
+ Name()+ ",第⼆个:"+ Value());
}
}
返回
"类"上的注解值获取到第⼀个:3333,第⼆个:4444
获取属性变量上注解的值
定义注解@Target(ElementType.FIELD)⽤于属性变量
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Banana {
String length();
String price();
}
获取
public class ParameterNameTest {
@Banana(length = "6666", price = "$888")
String something = "other information";
@Test
public void main() throws Exception {
Class<ParameterNameTest> clazz = ParameterNameTest.class;
// 获取 "属性变量" 上的注解的值
Field[] fields = DeclaredFields();
for(Field field: fields){
if(field.isAnnotationPresent(Banana.class)){
Banana bananaAnnotation = Annotation(Banana.class);
System.out.println("\"属性变量\"上的注解值获取到第⼀个:"
+ bananaAnnotation.length()+ ",第⼆个:"+ bananaAnnotation.price());            }
}
}
}
返回
springboot aop"属性变量"上的注解值获取到第⼀个:6666,第⼆个:$888
获取⽅法上注解的值
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Apple {
String color();
String number();
}
获取
public class ParameterNameTest {
@Apple(color = "红⾊", number = "5555")
public void method1(){
// ...
}
@Test
public void main() throws Exception {
Class<ParameterNameTest> clazz = ParameterNameTest.class;
// 获取 "⽅法"上的注解的值
Method[] methods = DeclaredMethods();
for (Method method: methods){
if(method.isAnnotationPresent(Apple.class)){
Apple appleAnnotation = Annotation(Apple.class);
System.out.println("\"⽅法\"上的注解值获取到第⼀个:"
+ lor()+ ",第⼆个:"+ appleAnnotation.number());            }
}
}
}
返回
"⽅法"上的注解值获取到第⼀个:红⾊,第⼆个:5555
获取" ⽅法参数 " 上注解的值
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Cherry {
String value();
}
获取

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。