国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - SpringBoot攔截器如何獲取http請求參數(shù)

SpringBoot攔截器如何獲取http請求參數(shù)

2020-09-11 00:29上帝愛吃蘋果-Soochow Java教程

這篇文章主要給大家介紹了SpringBoot攔截器如何獲取http請求參數(shù)的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

1.1、獲取http請求參數(shù)是一種剛需

我想有的小伙伴肯定有過獲取http請求的需要,比如想

  1. 前置獲取參數(shù),統(tǒng)計請求數(shù)據
  2. 做服務的接口簽名校驗
  3. 敏感接口監(jiān)控日志
  4. 敏感接口防重復提交

等等各式各樣的場景,這時你就需要獲取 HTTP 請求的參數(shù)或者請求body,一般思路有兩種,一種就是自定義個AOP去攔截目標方法,第二種就是使用攔截器。整體比較來說,使用攔截器更靈活些,因為每個接口的請求參數(shù)定義不同,使用AOP很難細粒度的獲取到變量參數(shù),本文主線是采用攔截器來獲取HTTP請求。

1.2、定義攔截器獲取請求

基于 spring-boot-starter-parent 2.1.9.RELEASE

看起來這個很簡單,這里就直接上code,定義個攔截器

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
 * @author axin
 * @summary HTTP請求攔截器
 */
@Slf4j
public class RequestInterceptor implements HandlerInterceptor {
 
  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
 
    //獲取請求參數(shù)
    String queryString = request.getQueryString();
    log.info("請求參數(shù):{}", queryString);
 
    //獲取請求body
    byte[] bodyBytes = StreamUtils.copyToByteArray(request.getInputStream());
    String body = new String(bodyBytes, request.getCharacterEncoding());
 
    log.info("請求體:{}", body);
    return true;
  }
}

然后把這個攔截器配置一下中:

?
1
2
3
4
5
6
7
8
9
10
11
/**
 * WebMVC配置,你可以集中在這里配置攔截器、過濾器、靜態(tài)資源緩存等
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
 
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new RequestInterceptor()).addPathPatterns("/**");
  }
}

定義個接口測試一下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
 * @author axin
 * @summary 提交測試接口
 */
@Slf4j
@RestController
public class MyHTTPController {
 
  @GetMapping("/v1/get")
  public void get(@RequestParam("one") String one,
          @RequestParam("two") BigDecimal number) {
    log.info("參數(shù):{},{}", one, number);
  }
 
 
  @PostMapping("/v1/post")
  public void check(@RequestBody User user) {
 
    log.info("{}", JSON.toJSONString(user));
  }
}

GET請求獲取請求參數(shù)示例:

SpringBoot攔截器如何獲取http請求參數(shù)

POST請求獲取請求Body示例:

SpringBoot攔截器如何獲取http請求參數(shù)

我們發(fā)現(xiàn)攔截器在獲取HTTP請求的body時出現(xiàn)了 400 (Required request body is missing: public void com.axin.world.controller.MyHTTPController.check(com.axin.world.domain.User));同時也發(fā)現(xiàn)攔截器竟然走了兩遍,這又是咋回事呢?

SpringBoot攔截器如何獲取http請求參數(shù)

1.3、為什么攔截器會重復調兩遍呢?

其實是因為 tomcat截取到異常后就轉發(fā)到/error頁面,就在這個轉發(fā)的過程中導致了springmvc重新開始DispatcherServlet的整個流程,所以攔截器執(zhí)行了兩次,我們可以看下第二次調用時的url路徑:

SpringBoot攔截器如何獲取http請求參數(shù)

1.4、ServletInputStream(CoyoteInputStream) 輸入流無法重復調用

而之前出現(xiàn)的 Required request body is missing 錯誤 其實是ServletInputStream被讀取后無法第二次再讀取了,所以我們要把讀取過的內容存下來,然后需要的時候對外提供可被重復讀取的ByteArrayInputStream。

對于MVC的過濾器來說,我們就需要重寫 ServletInputStream 的 getInputStream()方法。

1.5、自定義 HttpServletRequestWrapper

為了 重寫 ServletInputStream 的 getInputStream()方法,我們需要自定義一個 HttpServletRequestWrapper :

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**
* @author Axin
* @summary 自定義 HttpServletRequestWrapper 來包裝輸入流
*/
public class AxinHttpServletRequestWrapper extends HttpServletRequestWrapper {
 
  /**
   * 緩存下來的HTTP body
   */
  private byte[] body;
 
  public AxinHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
    super(request);
    body = StreamUtils.copyToByteArray(request.getInputStream());
  }
 
  /**
   * 重新包裝輸入流
   * @return
   * @throws IOException
   */
  @Override
  public ServletInputStream getInputStream() throws IOException {
    InputStream bodyStream = new ByteArrayInputStream(body);
    return new ServletInputStream() {
 
      @Override
      public int read() throws IOException {
        return bodyStream.read();
      }
 
      /**
       * 下面的方法一般情況下不會被使用,如果你引入了一些需要使用ServletInputStream的外部組件,可以重點關注一下。
       * @return
       */
      @Override
      public boolean isFinished() {
        return false;
      }
 
      @Override
      public boolean isReady() {
        return true;
      }
 
      @Override
      public void setReadListener(ReadListener readListener) {
 
      }
    };
  }
  
  @Override
  public BufferedReader getReader() throws IOException {
    InputStream bodyStream = new ByteArrayInputStream(body);
    return new BufferedReader(new InputStreamReader(getInputStream()));
  }
}

然后定義一個 DispatcherServlet子類來分派 上面自定義的 AxinHttpServletRequestWrapper :

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* @author Axin
* @summary 自定義 DispatcherServlet 來分派 AxinHttpServletRequestWrapper
*/
public class AxinDispatcherServlet extends DispatcherServlet {
 
  /**
   * 包裝成我們自定義的request
   * @param request
   * @param response
   * @throws Exception
   */
  @Override
  protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    super.doDispatch(new AxinHttpServletRequestWrapper(request), response);
  }
}

然后配置一下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
 * WebMVC配置,你可以集中在這里配置攔截器、過濾器、靜態(tài)資源緩存等
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
 
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new RequestInterceptor()).addPathPatterns("/**");
  }
 
  @Bean
  @Qualifier(DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
  public DispatcherServlet dispatcherServlet() {
    return new AxinDispatcherServlet();
  }
}

再調用一下 POST請求:

SpringBoot攔截器如何獲取http請求參數(shù)

請求成功!

1.5、總結一下 展望一下

如果你想對HTTP請求做些騷操作,那么前置獲取HTTP請求參數(shù)是前提,為此文本給出了使用MVC攔截器獲取參數(shù)的樣例。

在獲取HTTP Body 的時候,出現(xiàn)了 Required request body is missing 的錯誤,同時攔截器還出現(xiàn)執(zhí)行了兩遍的問題,這是因為 ServletInputStream被讀取了兩遍導致的,tomcat截取到異常后就轉發(fā)到 /error 頁面 被攔截器攔截到了,攔截器也就執(zhí)行了兩遍。

為此我們通過自定義 HttpServletRequestWrapper 來包裝一個可被重讀讀取的輸入流,來達到期望的攔截效果。

在獲取到HTTP的請求參數(shù)后,我們可以前置做很多操作,比如常用的服務端接口簽名驗證,敏感接口防重復請求等等。

個人水平有限,如果文章有邏輯錯誤或表述問題還請指出,歡迎一起交流。

到此這篇關于SpringBoot攔截器如何獲取http請求參數(shù)的文章就介紹到這了,更多相關SpringBoot攔截器獲取http請求參數(shù)內容請搜索服務器之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://www.cnblogs.com/keeya/p/13634015.html

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 国产精品亲子伦av一区二区三区 | 国产高清亚洲 | 亚洲电影一区 | 日韩精品一区二区三区四区 | 91精品国产色综合久久不卡蜜臀 | 亚洲精品电影在线观看 | 中文字幕一区二区三区四区不卡 | 国产女优| 国产亚洲精品久久久久久久 | 国产成人精品久久二区二区 | 天堂网中文在线 | 奇米一区二区三区 | 欧美在线免费视频 | 蜜桃臀一区二区三区 | 黄色综合 | av在线播放网站 | ts人妖另类精品视频系列 | 国产精久久久 | 国产精品1 | 日韩成人在线电影 | 久久这里只有精品免费 | 亚洲国产二区 | 成人黄色片网站 | 成年人在线免费观看视频网站 | 欧美美女爱爱 | 一区二区免费在线观看 | 91免费视频网站 | 国产精品视频播放 | 日本成人 | 日本激情综合网 | 国产精品一区二区久久 | 久久久久久国产免费 | 青青在线精品视频 | 久久亚洲综合 | 欧美日韩中文字幕 | 人成久久 | 99视频在线免费观看 | 亚洲国产免费av | 色图综合 | www.国产一区 | 久久久亚洲国产天美传媒修理工 |