最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

spring boot+自定義 AOP 實現(xiàn)全局校驗的實例代碼

 更新時間:2019年04月09日 16:07:06   作者:吃桃子的小松鼠  
最近公司重構(gòu)項目,重構(gòu)為最熱的微服務(wù)框架 spring boot, 重構(gòu)的時候遇到幾個可以統(tǒng)一處理的問題。這篇文章主要介紹了spring boot+自定義 AOP 實現(xiàn)全局校驗 ,需要的朋友可以參考下

最近公司重構(gòu)項目,重構(gòu)為最熱的微服務(wù)框架 spring boot, 重構(gòu)的時候遇到幾個可以統(tǒng)一處理的問題,也是項目中經(jīng)常遇到,列如:統(tǒng)一校驗參數(shù),統(tǒng)一捕獲異常。。。

僅憑代碼 去控制參數(shù)的校驗,有時候是冗余的,但通過框架支持的 去控制參數(shù)的校驗,是對于開發(fā)者很友好,先看下面的例子

 @NotEmpty(message="手機號不能為空")
   @Size(min=11,max=11,message="手機號碼長度不正確")
   @Pattern(regexp=StringUtils.REGEXP_MOBILE,message="手機號格式不正確")
  private String mobile;

這是spring boot支持的 校驗注解,然后我們在 contoller層 加上@Valid 注解 就可以達到校驗的目的。這是一種框架自帶的

本章 就展示一種 自定義的 AOP 校驗,首先 寫一個注解,注解里面可以寫上 我們需要校驗的規(guī)則, 比如長度,正則。。。

@Documented
@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidateParam {
  int min() default 0;
  int max() default Integer.MAX_VALUE;
  String message() default "params is not null";
  String regexp();
  Class<?>[] groups() default { };
   Class<? extends Payload>[] payload() default { };
   boolean isNotNull() default true;
}

然后定義一個AOP類

package com.onecard.primecard.common.aop;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.regex.Pattern;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
import com.jfcf.core.dto.ResultData;
import com.onecard.core.support.util.StringUtils;
import com.onecard.primecard.common.annotation.ValidateParam;
import com.onecard.primecard.common.utils.ResultDataUtil;
/**
 * 全局 切面類(校驗參數(shù))
 * 
 * @author Administrator
 *
 */
@Aspect
@Component
public class GobalHandlerAspect {
  private static Logger logger = LoggerFactory.getLogger(GobalHandlerAspect.class);
  @Pointcut("execution(* 包名.controller..*.*(..)) && execution(* 包名.controller..*.*(..))")
  public void checkAspect(){};
  @Before("checkAspect()")
  public void befor(JoinPoint joinPoint) throws Exception{
    //前置統(tǒng)一輸出參數(shù)
    Object[] args = joinPoint.getArgs();
    if(args != null && args.length>0){
      Object obj = args[0];
      ParameterizedType pt = (ParameterizedType)obj.getClass().getGenericSuperclass();
      Class<?> classzz = (Class<?>) pt.getActualTypeArguments()[0];
      logger.info("【小X卡】-【請求實體入?yún)ⅰ浚?+classzz.newInstance().toString());
    }
  }
  @Around("checkAspect()")
  public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
    //校驗參數(shù)
    Object[] args = joinPoint.getArgs();
    Object obj = null;
    if(args != null && args.length > 0){
      obj = args[0];
      Class classzz = obj.getClass();
      //沒有順序和秩序的數(shù)組
      Field[] fieldArray = classzz.getDeclaredFields();
      ArrayList<Field> fieldList = new ArrayList<Field>(Arrays.asList(fieldArray));
      String res = checkParam(fieldList,obj);
      if(StringUtils.isNotNull(res)){
        return ResultDataUtil.result(ResultData.STATUS_PARAM_ERROR, res);
      }
    }
    return joinPoint.proceed();
  }
  private String checkParam(ArrayList<Field> fieldList, Object obj) throws Exception {
    for(Field field : fieldList){
      ValidateParam validateParam = field.getAnnotation(ValidateParam.class);
      logger.info("【小X卡】獲取注解值:"+validateParam.isNotNull()+"min="+validateParam.min()+"max="+validateParam.max());
      Method method = obj.getClass().getMethod("get"+getMethodName(field.getName()));
      logger.info("【小X卡】入?yún)嶓w方法名稱:"+method.getName());
      if(method != null){
        Object val = method.invoke(obj);
        logger.info("【小x卡】回調(diào)方法:"+val);
        if(validateParam != null && validateParam.isNotNull() == true){
          if(null == val || "".equals(val) ){
            return field.getName()+"必填參數(shù)為空";
          }
        }
        if(validateParam.min()==11 && validateParam.max() == 11){
          if(val.toString().length() != 11){
            return field.getName()+"請輸入?yún)?shù)正確的長度";
          }
        }
        if(validateParam.regexp().equals(StringUtils.REGEXP_MOBILE)){
          if(!Pattern.matches(StringUtils.REGEXP_MOBILE, val.toString())){
            return field.getName()+"參數(shù)格式錯誤";
          }
        }
      }
    }
    return null;
  }
   /**
   * 方法首字母大寫
   * @param fieldName
   * @return
   */
  private String getMethodName(String fieldName) {
    StringBuffer buffer = new StringBuffer();
    String firstLetter = fieldName.substring(0, 1).toUpperCase();
    return buffer.append(firstLetter).append(fieldName.substring(1, fieldName.length())).toString();
  }    
 }

定義一個切點 @Pointcut, 用execution 表達式,去獲取要校驗的 某個類 和某個方法, 也就是連接點,然后 用定義一個通知,上面代碼中有2個通知,一個前置通知@Before,一個環(huán)繞通知@Around,我們使用功能最強大的環(huán)繞通知。

通過上面的代碼可以看出  首先獲取參數(shù),然后通過反射機制 獲取 入?yún)ο笾械娜孔侄危?再去獲取 我們在字段中加 我們自定義注解的字段,通過反射方法的回調(diào),獲取字段值,對值做判斷, 返回校驗結(jié)果。

總結(jié)

以上所述是小編給大家介紹的spring boot+自定義 AOP 實現(xiàn)全局校驗的實例代碼,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復(fù)大家的!

相關(guān)文章

  • Spring中ThreadLocal的解析

    Spring中ThreadLocal的解析

    這篇文章主要介紹了Spring中ThreadLocal的解析,Spring通過各種DAO模板類降低了開發(fā)者使用各種數(shù)據(jù)持久技術(shù)的難度。這些模板類都是線程安全的,也就是說,多個DAO可以復(fù)用同一個模板實例而不會發(fā)生沖突,下面一起進入文章學(xué)子詳細內(nèi)容吧
    2022-01-01
  • java實現(xiàn)udp通訊的代碼

    java實現(xiàn)udp通訊的代碼

    這篇文章主要為大家詳細介紹了java實現(xiàn)udp通訊的代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • Spring零基礎(chǔ)到進階之鴻蒙開篇

    Spring零基礎(chǔ)到進階之鴻蒙開篇

    Spring框架是一個開放源代碼的J2EE應(yīng)用程序框架,由Rod Johnson發(fā)起,是針對bean的生命周期進行管理的輕量級容器(lightweight container)。 Spring解決了開發(fā)者在J2EE開發(fā)中遇到的許多常見的問題,提供了功能強大IOC、AOP及Web MVC等功能
    2022-07-07
  • @RequestParam 接收參數(shù)的值為null的處理方式

    @RequestParam 接收參數(shù)的值為null的處理方式

    這篇文章主要介紹了@RequestParam 接收參數(shù)的值為null的處理方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java中seata框架的XA模式詳解

    Java中seata框架的XA模式詳解

    這篇文章主要介紹了Java中seata框架的XA模式詳解,Seata?是一款開源的分布式事務(wù)解決方案,致力于提供高性能和簡單易用的分布式事務(wù)服務(wù),Seata?將為用戶提供了?AT、TCC、SAGA?和?XA?事務(wù)模式,為用戶打造一站式的分布式解決方案,需要的朋友可以參考下
    2023-08-08
  • 使用Feign調(diào)用注解組件(實現(xiàn)字段賦值功能)

    使用Feign調(diào)用注解組件(實現(xiàn)字段賦值功能)

    這篇文章主要介紹了使用Feign調(diào)用注解組件(實現(xiàn)字段賦值功能),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java 畫時鐘遇到的問題及解決方案

    Java 畫時鐘遇到的問題及解決方案

    我是一個剛?cè)腴T的小菜鳥,希望我寫的東西可以幫助和我一樣剛?cè)腴T的兄弟們少走一些彎路,也希望大佬們可以多指點指點我。感謝!解決在畫時鐘遇到的問題讓我花費不少時間...說兩個困擾我比較久的
    2021-11-11
  • IntelliJ IDEA 2019.1.1 for MAC 下載和注冊碼激活教程圖解

    IntelliJ IDEA 2019.1.1 for MAC 下載和注

    這篇文章主要介紹了IntelliJ IDEA 2019.1.1 for MAC 下載和注冊碼激活,教程,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • 新手學(xué)習(xí)Java對Redis簡單操作

    新手學(xué)習(xí)Java對Redis簡單操作

    這篇文章主要介紹了新手學(xué)習(xí)Java對Redis簡單操作,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-04-04
  • Spring Boot使用Servlet及Filter過程詳解

    Spring Boot使用Servlet及Filter過程詳解

    這篇文章主要介紹了Spring Boot使用Servlet及Filter過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-07-07

最新評論

阳朔县| 龙川县| 天水市| 昌平区| 遵义市| 印江| 当阳市| 贞丰县| 都昌县| 兴业县| 丰镇市| 台北县| 昌吉市| 如皋市| 化德县| 玛纳斯县| 兴和县| 奇台县| 同仁县| 察雅县| 石嘴山市| 乐山市| 抚松县| 云龙县| 海丰县| 丹东市| 正宁县| 德庆县| 汉沽区| 奉贤区| 松桃| 双桥区| 鹤岗市| 达孜县| 沈阳市| 安龙县| 庆城县| 馆陶县| 锦州市| 邹城市| 历史|