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

SpringBoot使用自定義注解實(shí)現(xiàn)權(quán)限攔截的示例

 更新時(shí)間:2017年09月30日 14:25:11   作者:小雨轉(zhuǎn)暴雨  
本篇文章主要介紹了SpringBoot使用自定義注解實(shí)現(xiàn)權(quán)限攔截的示例,具有一定的參考價(jià)值,有興趣的可以了解一下

本文介紹了SpringBoot使用自定義注解實(shí)現(xiàn)權(quán)限攔截的示例,分享給大家,具體如下:

HandlerInterceptor(處理器攔截器)

常見(jiàn)使用場(chǎng)景

  • 日志記錄: 記錄請(qǐng)求信息的日志, 以便進(jìn)行信息監(jiān)控, 信息統(tǒng)計(jì), 計(jì)算PV(page View)等
  • 性能監(jiān)控:
  • 權(quán)限檢查:
  • 通用行為:

使用自定義注解實(shí)現(xiàn)權(quán)限攔截

首先HandlerInterceptor了解

在HandlerInterceptor中有三個(gè)方法:

public interface HandlerInterceptor {

  // 在執(zhí)行目標(biāo)方法之前執(zhí)行
  boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler)throws Exception;

  // 執(zhí)行目標(biāo)方法之后執(zhí)行
  void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)throws Exception;

  // 在請(qǐng)求已經(jīng)返回之后執(zhí)行
  void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception;

}

在以上注釋中已經(jīng)寫(xiě)明執(zhí)行順序, 測(cè)試及測(cè)試結(jié)果如下:

public class TestInterceptor implements HandlerInterceptor {

  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    System.out.println("preHandler");
    return true;
  }

  @Override
  public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    System.out.println("postHandler");
  }

  @Override
  public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    System.out.println("afterCompletion");
  }
}

結(jié)果:

preHandler
postHandler
afterCompletion

如何配置攔截器后面講:

下面來(lái)講講這個(gè)攔截器是攔截的什么?

方法攔截器HandlerInterceptor

我們使用SpringMVC都知道SpringMVC是基于方法的請(qǐng)求處理, 和Struts2有明顯區(qū)別(我是這么理解的), 并且Controller是單例模式, 所有請(qǐng)求都是從DispatcherServlet來(lái)調(diào)用請(qǐng)求url對(duì)應(yīng)的方法的(處理器映射器的功能), 那么它是一個(gè)方法攔截器, 如何知道呢?

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  System.out.println(handler.getClass());
  return true;
}

執(zhí)行結(jié)果:

class org.springframework.web.method.HandlerMethod

已經(jīng)看到攔截器如何工作, 并且知道它是方法級(jí)別的攔截器, 那么接下來(lái)看看如何配置攔截器, 讓它在服務(wù)器運(yùn)行期間起作用

實(shí)現(xiàn)HandlerInterceptor

實(shí)現(xiàn)HandlerInterceptor接口或者繼承HandlerInterceptorAdapter類(lèi)
HandlerInterceptorAdapter適配器是對(duì)HandlerInterceptor接口做了默認(rèn)實(shí)現(xiàn), 這種適配器模式, 是為了方便開(kāi)發(fā)者只去想要復(fù)寫(xiě)方法, 其他方法采取默認(rèn)措施.

上面的TestInterceptor就是一個(gè)Demo, 具體可以按需求在我們想要攔截的位置進(jìn)行相應(yīng)的邏輯處理

配置攔截器

從Spring4.x開(kāi)始, 就支持注解配置具體是使用@Configuration注解標(biāo)注一個(gè)普通類(lèi), 使該類(lèi)成為配置類(lèi), 可以在該類(lèi)中定義Bean, 以及注入一些配置參數(shù)等.

首先, 我們要配置攔截器,就需要想SpringMvc的攔截鏈中取注入我們的攔截器, 這樣才能請(qǐng)求進(jìn)來(lái)時(shí)去攔截我們想要攔截的請(qǐng)求, 所以, 需要我們新建一個(gè)普通類(lèi), 使用@Configuration注解標(biāo)注在類(lèi)名上, 并且讓該類(lèi)繼承WebMvcConfigurerAdapter,為什么不實(shí)現(xiàn)WebMvcConfigurer接口呢? 因?yàn)榉椒ㄌ?我們不需要復(fù)寫(xiě)其中所有方法...

下面讓我們新建一個(gè)配置類(lèi), 來(lái)配置我們的攔截器

@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {

  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new TestInterceptor()).addPathPatterns("/**");
  }
}

復(fù)寫(xiě)addInterceptors之后, 當(dāng)我們的服務(wù)器啟動(dòng)時(shí), 會(huì)自動(dòng)調(diào)用這個(gè)方法, 參數(shù)怎么傳我們都不用管(目前是java初級(jí)階段, 沒(méi)空研究Spring深層原理), 我們只要知道這個(gè)方法一定會(huì)被調(diào)用就行了.

我們直接new一個(gè)自定義攔截器, 注冊(cè)到整個(gè)攔截鏈中, 并且制定攔截路徑, 這樣當(dāng)滿(mǎn)足請(qǐng)求url攔截配置時(shí), 我們的自定義攔截器就會(huì)執(zhí)行相應(yīng)的方法了.

攔截方法是非常靈的, 除了攔截配置的, 也可以攔截非匹配的, 也可以根據(jù)正則表達(dá)式攔截請(qǐng)求

至此, 我們的攔截器就完成了, 接下來(lái)自定義權(quán)限相關(guān)注解

自定義權(quán)限注解

定義一個(gè)@interface類(lèi)

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Access {

  String[] value() default {};

  String[] authorities() default {};

  String[] roles() default {};

}

@Target注解是標(biāo)注這個(gè)類(lèi)它可以標(biāo)注的位置:

常用的元素類(lèi)型(ElementType):

public enum ElementType {
  /** Class, interface (including annotation type), or enum declaration */
  // TYPE類(lèi)型可以聲明在類(lèi)上或枚舉上或者是注解上
  TYPE,
  /** Field declaration (includes enum constants) */
  // FIELD聲明在字段上
  FIELD,
  /** Method declaration */
  // 聲明在方法上
  METHOD,
  /** Formal parameter declaration */
  // 聲明在形參列表中
  PARAMETER,
  /** Constructor declaration */
  // 聲明在構(gòu)造方法上
  CONSTRUCTOR,
  /** Local variable declaration */
  // 聲明在局部變量上
  LOCAL_VARIABLE,
  /** Annotation type declaration */
  ANNOTATION_TYPE,
  /** Package declaration */
  PACKAGE,
  /**
   * Type parameter declaration
   *
   * @since 1.8
   */
  TYPE_PARAMETER,
  /**
   * Use of a type
   *
   * @since 1.8
   */
  TYPE_USE
}

@Retention注解表示的是本注解(標(biāo)注這個(gè)注解的注解保留時(shí)期)

public enum RetentionPolicy {
  /**
   * Annotations are to be discarded by the compiler.
   */
  // 源代碼時(shí)期
  SOURCE,
  /**
   * Annotations are to be recorded in the class file by the compiler
   * but need not be retained by the VM at run time. This is the default
   * behavior.
   */
  // 字節(jié)碼時(shí)期, 編譯之后
  CLASS,
  /**
   * Annotations are to be recorded in the class file by the compiler and
   * retained by the VM at run time, so they may be read reflectively.
   *
   * @see java.lang.reflect.AnnotatedElement
   */
   // 運(yùn)行時(shí)期, 也就是一直保留, 通常也都用這個(gè)
  RUNTIME
}

@Documented是否生成文檔的標(biāo)注, 也就是生成接口文檔是, 是否生成注解文檔

注解說(shuō)完了, 下面需要到對(duì)應(yīng)的controller的方法中取添加注解, 配置該方法允許的權(quán)限

在方法上配置權(quán)限

@RestController
public class HelloController {

  @RequestMapping(value = "/admin", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = RequestMethod.GET)
  // 配置注解權(quán)限, 允許身份為admin, 或者說(shuō)允許權(quán)限為admin的人訪問(wèn)
  @Access(authorities = {"admin"})
  public String hello() {
    return "Hello, admin";
  }
}

編寫(xiě)權(quán)限邏輯

// 自定義一個(gè)權(quán)限攔截器, 繼承HandlerInterceptorAdapter類(lèi)
public class AuthenticationInterceptor extends HandlerInterceptorAdapter {

  // 在調(diào)用方法之前執(zhí)行攔截
  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    // 將handler強(qiáng)轉(zhuǎn)為HandlerMethod, 前面已經(jīng)證實(shí)這個(gè)handler就是HandlerMethod
    HandlerMethod handlerMethod = (HandlerMethod) handler;
    // 從方法處理器中獲取出要調(diào)用的方法
    Method method = handlerMethod.getMethod();
    // 獲取出方法上的Access注解
    Access access = method.getAnnotation(Access.class);
    if (access == null) {
    // 如果注解為null, 說(shuō)明不需要攔截, 直接放過(guò)
      return true;
    }
    if (access.authorities().length > 0) {
      // 如果權(quán)限配置不為空, 則取出配置值
      String[] authorities = access.authorities();
      Set<String> authSet = new HashSet<>();
      for (String authority : authorities) {
      // 將權(quán)限加入一個(gè)set集合中
        authSet.add(authority);
      }
      // 這里我為了方便是直接參數(shù)傳入權(quán)限, 在實(shí)際操作中應(yīng)該是從參數(shù)中獲取用戶(hù)Id
      // 到數(shù)據(jù)庫(kù)權(quán)限表中查詢(xún)用戶(hù)擁有的權(quán)限集合, 與set集合中的權(quán)限進(jìn)行對(duì)比完成權(quán)限校驗(yàn)
      String role = request.getParameter("role");
      if (StringUtils.isNotBlank(role)) {
        if (authSet.contains(role)) {
        // 校驗(yàn)通過(guò)返回true, 否則攔截請(qǐng)求
          return true;
        }
      }
    }
    // 攔截之后應(yīng)該返回公共結(jié)果, 這里沒(méi)做處理
    return false;
  }

}

至此, 我們啟動(dòng)服務(wù)器, 訪問(wèn)接口, 就能看到效果, 這里不做示范了

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Hibernate管理Session和批量操作分析

    Hibernate管理Session和批量操作分析

    這篇文章主要介紹了Hibernate管理Session和批量操作的技巧,包括Hibernate管理Session、批量處理數(shù)據(jù)等的常用技巧及注意事項(xiàng),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2014-12-12
  • springboot工程jar包部署到云服務(wù)器的方法

    springboot工程jar包部署到云服務(wù)器的方法

    這篇文章主要介紹了springboot工程jar包部署到云服務(wù)器的方法,本文通過(guò)實(shí)例介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2018-05-05
  • Java的編譯時(shí)錯(cuò)誤和運(yùn)行時(shí)錯(cuò)誤問(wèn)題

    Java的編譯時(shí)錯(cuò)誤和運(yùn)行時(shí)錯(cuò)誤問(wèn)題

    這篇文章主要介紹了Java的編譯時(shí)錯(cuò)誤和運(yùn)行時(shí)錯(cuò)誤問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • SpringBoot Shiro授權(quán)實(shí)現(xiàn)過(guò)程解析

    SpringBoot Shiro授權(quán)實(shí)現(xiàn)過(guò)程解析

    這篇文章主要介紹了SpringBoot Shiro授權(quán)實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • spring如何使用命名空間p簡(jiǎn)化bean的配置

    spring如何使用命名空間p簡(jiǎn)化bean的配置

    這篇文章主要介紹了spring如何使用命名空間p簡(jiǎn)化bean的配置,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • JDK源碼之線程并發(fā)協(xié)調(diào)神器CountDownLatch和CyclicBarrier詳解

    JDK源碼之線程并發(fā)協(xié)調(diào)神器CountDownLatch和CyclicBarrier詳解

    我一直認(rèn)為程序是對(duì)于現(xiàn)實(shí)世界的邏輯描述,而在現(xiàn)實(shí)世界中很多事情都需要各方協(xié)調(diào)合作才能完成,就好比完成一個(gè)平臺(tái)的交付不可能只靠一個(gè)人,而需要研發(fā)、測(cè)試、產(chǎn)品以及項(xiàng)目經(jīng)理等不同角色人員進(jìn)行通力合作才能完成最終的交付
    2022-02-02
  • Spring定時(shí)任務(wù)@Scheduled注解(cron表達(dá)式fixedRate?fixedDelay)

    Spring定時(shí)任務(wù)@Scheduled注解(cron表達(dá)式fixedRate?fixedDelay)

    這篇文章主要為大家介紹了Spring定時(shí)任務(wù)@Scheduled注解(cron表達(dá)式fixedRate?fixedDelay)使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • Zookeeper如何實(shí)現(xiàn)分布式服務(wù)配置中心詳解

    Zookeeper如何實(shí)現(xiàn)分布式服務(wù)配置中心詳解

    Zookeeper在實(shí)際使用場(chǎng)景很多,比如配置中心,分布式鎖,注冊(cè)中心等,下面這篇文章主要給大家介紹了關(guān)于Zookeeper如何實(shí)現(xiàn)分布式服務(wù)配置中心的相關(guān)資料,需要的朋友可以參考下
    2021-11-11
  • 提高開(kāi)發(fā)效率Live?Templates使用技巧詳解

    提高開(kāi)發(fā)效率Live?Templates使用技巧詳解

    這篇文章主要為大家介紹了提高開(kāi)發(fā)效率Live?Templates使用技巧詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • 深入淺出講解Java比較器及數(shù)學(xué)常用類(lèi)

    深入淺出講解Java比較器及數(shù)學(xué)常用類(lèi)

    這篇文章主要介紹了深入淺出講解Java比較器及數(shù)學(xué)常用類(lèi),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09

最新評(píng)論

娄烦县| 福安市| 宜城市| 桦川县| 庆城县| 金坛市| 沅江市| 吉隆县| 鲁山县| 仁怀市| 沅陵县| 察哈| 驻马店市| 南和县| 渝中区| 芮城县| 中卫市| 高碑店市| 六枝特区| 英山县| 贡觉县| 南召县| 都安| 德江县| 合江县| 杭锦旗| 鹤峰县| 海南省| 高邮市| 通河县| 昌黎县| 乌拉特后旗| 泸溪县| 寻甸| 武鸣县| 庆云县| 方城县| 太和县| 镶黄旗| 当雄县| 松原市|