<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          手寫(xiě)web服務(wù)器:實(shí)現(xiàn)簡(jiǎn)單filter攔截邏輯

          共 6351字,需瀏覽 13分鐘

           ·

          2021-06-12 06:33

          前言

          今天早上起床的時(shí)候,我還在想應(yīng)該實(shí)現(xiàn)哪個(gè)組件,想了半天,發(fā)現(xiàn)基本上常用的注解組件都被我們給實(shí)現(xiàn)了(當(dāng)然,雖然都實(shí)現(xiàn)了,但是基本上都是簡(jiǎn)易版),最后想來(lái)想去覺(jué)得filter可以實(shí)現(xiàn)下,畢竟沒(méi)有這個(gè)模塊,項(xiàng)目中的就沒(méi)法實(shí)現(xiàn)權(quán)限控制了。

          在開(kāi)始的時(shí)候,我已經(jīng)知道filter的難點(diǎn)是地址的匹配,也就是如何把我們配置的地址轉(zhuǎn)換為正則表達(dá)式,最后發(fā)現(xiàn)這塊涉及的知識(shí)點(diǎn)有點(diǎn)多,所以今天就只演示通配地址,即/*。

          好了,我們一起來(lái)看下吧。

          過(guò)濾器實(shí)現(xiàn)過(guò)程

          定義注解

          這里依然很輕車(chē)熟路,注解的配置我增加了很多屬性,最核心的就是urlPatterns,也就是我們的攔截地址。

          @Target(ElementType.TYPE)
          @Retention(RetentionPolicy.RUNTIME)
          public @interface WebFilter {
              String[] value() default {};

              String description() default "";

              String displayName() default "";

              String[] urlPatterns() default {};
          }

          定義Filter接口

          這里參考了javaEEfilter接口

          public interface Filter {
              default void init() {}

              void doFilter(Request request, Response response, FilterChain filterChain) throws IOException;

              default void destrory() {}
          }

          public interface FilterChain {
              /**
               * filter調(diào)用鏈
               * @param request
               * @param response
               * @throws IOException
               */

              void doFilter(Request request, Response response) throws IOException;
          }

          定義filter

          加上webFilter,并配置攔截地址,實(shí)現(xiàn)doFilter方法

          @WebFilter(urlPatterns = {"/*"}, description = "test filter")
          public class TestFilter implements Filter{
              @Override
              public void doFilter(Request request, Response response, FilterChain filterChain) throws IOException {
                  System.out.println(String.format("過(guò)濾器TestFilter被訪問(wèn),攔截地址:%s", request.getRequestHear().getRequestMapping()));
                  if (Objects.nonNull(filterChain)) {
                      filterChain.doFilter(request, response);
                  }
              }
          }

          過(guò)濾器初始化

          這里主要是配合IoC,拿到過(guò)濾器的配置信息,并實(shí)例化filter

          private static Map<Filter, String[]> filterUrlPatternsMap = Maps.newHashMap();

              private static LinkedList<Filter> filterLinkedList = Lists.newLinkedList();

              public static Map<Filter, String[]> getFilterUrlPatternsMap() {
                  return filterUrlPatternsMap;
              }

              public static LinkedList<Filter> getFilterLinkedList() {
                  return filterLinkedList;
              }

              public static void init(Class zClass) throws IllegalAccessException, InstantiationException {
                  Annotation webFilter = zClass.getAnnotation(WebFilter.class);
                  if (Objects.nonNull(webFilter)) {
                      String[] urlPatterns = ((WebFilter) webFilter).urlPatterns();
                      Filter filter = (Filter)zClass.newInstance();
                      filterUrlPatternsMap.put(filter, urlPatterns);
                      filterLinkedList.add(filter);
                  }
              }

          修改disPatcher方法

          這里就是對(duì)請(qǐng)求地址進(jìn)行過(guò)濾,當(dāng)匹配到請(qǐng)求時(shí),執(zhí)行匹配到過(guò)濾器的doFilter方法

          Map<Filter, String[]> filterUrlPatternsMap = FilterHandler.getFilterUrlPatternsMap();
                      LinkedList<Filter> filterLinkedList = FilterHandler.getFilterLinkedList();
                      ListIterator<Filter> filterListIterator = filterLinkedList.listIterator();
                      while (filterListIterator.hasNext()) {
                          Filter filter = filterListIterator.next();
                          String[] values = filterUrlPatternsMap.get(filter);
                          for (String value : values) {
                              if(Pattern.matches(value.replace('/''.'), requestMapping)) {
                                  filter.doFilter(request, response, null);
                              }

                          }
                      }

          測(cè)試

          我們用瀏覽器訪問(wèn)任意地址,比如/testAutowire,會(huì)看到doFilter方法被執(zhí)行了,控制臺(tái)打印如下信息:

          說(shuō)明,我們的filter已經(jīng)起作用了,是不是很簡(jiǎn)單呀。

          總結(jié)

          雖然filter的核心功能實(shí)現(xiàn)了,但作為一個(gè)合格的web服務(wù)器,攔截器也得夠健壯,夠靈活,所以還有很多工作要做:

          比如要實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用,就是實(shí)現(xiàn)多個(gè)過(guò)濾器的順序調(diào)用,層層調(diào)用,層層返回,形成調(diào)用鏈,這一塊后面要進(jìn)一步實(shí)現(xiàn);

          另外一個(gè)問(wèn)題就是,我們要實(shí)現(xiàn)更靈活的地址匹配,前面我也說(shuō)了,目前的地址只實(shí)現(xiàn)了通配和嚴(yán)格匹配兩種,正則表達(dá)式支持的也不夠完美,這一塊也是后面要優(yōu)化的點(diǎn)。

          好了,核心內(nèi)容到這里就結(jié)束了,但我想說(shuō)兩句閑話,這兩天在刷一個(gè)制作精良的劇——《覺(jué)醒年代》,這應(yīng)該是這幾年,我看過(guò)最有價(jià)值的電視劇了,讓我對(duì)很多革命先烈有了更深刻的認(rèn)識(shí),有興趣的小伙伴可以去看下,真的很贊。

          下面是項(xiàng)目的開(kāi)源倉(cāng)庫(kù),有興趣的小伙伴可以去看看,如果有想法的小伙伴,我真心推薦你自己動(dòng)個(gè)手,自己寫(xiě)一下,真的感覺(jué)不錯(cuò):

          https://github.com/Syske/syske-boot
          - END -


          瀏覽 66
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天天干夜啪 | 爱操逼av| 亚洲网站免费在线观看 | 欧美及黄视频在线观看 | 在线观看国产成人AV一天堂 |