<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                若想在每次請求時均在后臺處理以下邏輯: ![](https://img.kancloud.cn/70/fe/70fe2ea55b9d93f1a3a01ff719a3fec0_296x194.png) 按當前掌握的知識便需要在每個控制器的方法中加入相應的處理認證令牌的代碼。以上個章節中剛剛完成的StudentController為例,示例代碼如下: ```java public class StudentController { ... @GetMapping("{id}") public Student getById(@PathVariable Long id) { // 進行令牌認證與分發 ? return this.studentService.findById(id); } @PostMapping @ResponseStatus(HttpStatus.CREATED) public Student save(@RequestBody Student student) { // 進行令牌認證與分發 ? return studentService.save(student); } ``` * ?? 在進行邏輯處理前先進行令牌的驗證與分發。 這種方案是可行的,按此方案則需要先開發一個驗證與分發令牌的方法,然后在各個控制器的方法中來調用此方法來完成令牌分發的操作。 同時這種方案由于對原有代碼進行了過多的干預,所以必然也不是最佳的。在團隊開發的過程中,我們希望能夠將認證的模塊與其它的模塊可以做到單獨、并列開發。每個模塊都是互相獨立的。盡量的降低各個模塊間的耦合度。 # filter過濾器 成熟的spring當前早早的就已經解決了此類問題并形成了最佳實踐,那就是filter過濾器。在計算機的世界里,過濾器與現實生活中稍有不同。現實生活中的過濾器的最終目的都是把不符合要求的過濾掉,把符合要求的留下來,所以過濾后的物質不會多于過濾前的物質。而計算機中的過濾器即可以越過濾越少,也可以越過濾越多。過濾后的數據的多少完全取決于所實現的代碼。 不止如此spring中的過濾器在進行http請求過濾時,不但可以過濾請求的數據,還可以過濾返回的數據。加入過濾器器具前后臺的令牌交互的過程如下圖: ![](https://img.kancloud.cn/2a/cd/2acdc94ee4440132f4a062dbf7232b9b_809x471.png) ## 實現過濾器 使用idea打開后臺項目,并在項目根目錄下新建`filter`包,然后在此包下新建`TokenFilter`類。 ![](https://img.kancloud.cn/a4/60/a4603eb777d1481b5411047c21952271_506x321.png) 初始化如下: ``` package com.mengyunzhi.springbootstudy.filter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * 令牌過濾器 * 繼承HttpFilter以過濾http請求與響應 * @author panjie */ public class TokenFilter extends HttpFilter ?{ @Override ? protected void doFilter(HttpServletRequest request?, HttpServletResponse response?, FilterChain chain) throws IOException, ServletException { // 獲取 header中的token并做有效性驗證 // 如果無效則分發送的token // 轉發數據。spring開始調用控制器中的特定方法 chain.doFilter(request, response); // 為http響應加入新token后返回 } } ``` * ? 繼承HttpFilter。該HttpFilter進行一些自動判斷后將數據發送到doFilter方法。 * ? 此doFilter方法已存在于HttpFilter中,所以在此以關鍵字聲明 * ? 改變此對象可以達到改變http請求的目的 * ? 改變此對象可以達到改變http響應的目的 ## 配置過濾器 若想使某個過濾器生效,還需要:一、對項目進行配置以啟用其打描過濾器的功能;二、使用特定的注解來告知spring某個過濾器此時的狀態為**生效**。 有了這兩項配置以后spring在啟動應用時便會將聲明了**生效**狀態的過濾器加入到項目中來了。此時若有http請求則會執行過濾器中的代碼。在進行配置以前,分別于TokenFilter及TeacherController中加入以下日志代碼以更好的在控制臺中查看其執行過程。 filter/TokenFilter.java ```java public class TokenFilter extends HttpFilter { private final static Logger logger = LoggerFactory.getLogger(TokenFilter.class); ? @Override protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { // 獲取 header中的token并做有效性驗證 // 如果無效則分發送的token logger.info("在控制器被調用以前執行"); ? // 轉發數據。spring開始調用控制器中的特定方法 chain.doFilter(request, response); logger.info("在控制器被調用以后執行"); ? // 為http響應加入新token后返回 } } ``` controller/TeacherController.java ```java @GetMapping @CrossOrigin("*") public List<Teacher> getAll() { logger.info("調用TeacherController的getAll方法"); ... ``` 然后于IDEA中建立一個Http Request(忘記如何建立的話請參數2.4.2)測試,內容如下: ``` GET http://localhost:8080/Teacher ``` 啟動數據庫及后臺應用后,執行該測試并觀察控制臺: ![](https://img.kancloud.cn/70/03/70031102f47f7c183d6a6b531379b40b_654x136.png) ``` 2020-02-10 16:39:50.733 INFO 24047 --- [nio-8080-exec-4] c.m.s.controller.TeacherController : 調用TeacherController的getAll方法 ``` 在執行http requrest時,控制臺中新增了一條info等級的日志。說時此時TokenFilter中的doFilter方法并未執行。 ### 啟用過濾器掃描功能 SpringBootStudyApplication.java ```java @SpringBootApplication @ServletComponentScan ? public class SpringBootStudyApplication { ``` * ? 啟用Servlet組件掃描功能。 >[info] ServletComponent有三種類型:WebServlet、WebFilter及WebListener ### 加入注解 filter/TokenFilter.java ``` @WebFilter ? public class TokenFilter extends HttpFilter { ``` * ? 告知spring: 本類是個生效的過濾器 ## 測試 重新啟動后臺應用并發起http request測試,查看控制臺得到如下info等級信息。 去除debug等級的日志后如下 ``` 2020-02-10 16:45:40.563 INFO 29832 --- [nio-8080-exec-1] c.m.springbootstudy.filter.TokenFilter : 在控制器被調用以前執行 ... 2020-02-10 16:45:40.578 INFO 29832 --- [nio-8080-exec-1] c.m.s.controller.TeacherController : 調用TeacherController的getAll方法 ... 2020-02-10 16:45:40.623 INFO 29832 --- [nio-8080-exec-1] c.m.springbootstudy.filter.TokenFilter : 在控制器被調用以后執行 ``` # 參考文檔 | 名稱 | 鏈接 | 預計學習時長(分) | | --- | --- | --- | | 源碼地址 | [https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step5.2.1](https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step5.2.1) | - | | servlet filter | [https://www.oracle.com/technetwork/java/filters-137243.html](https://www.oracle.com/technetwork/java/filters-137243.html) | - | | @ServletComponentScan | [https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/web/servlet/ServletComponentScan.html](https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/web/servlet/ServletComponentScan.html) | - | | @WebFilter | [https://docs.oracle.com/javaee/7/api/javax/servlet/annotation/WebFilter.html?is-external=true](https://docs.oracle.com/javaee/7/api/javax/servlet/annotation/WebFilter.html?is-external=true) | - |
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看