首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Spring MVC 直接獲取請求與響應原始字符串的方法

     編輯:程式設計綜合問答

獲取請求原始字符串 (Request Body)

Controller 方法參數直接聲明 `HttpServletRequest request`,然後讀取輸入流:

@PostMapping("/api/data")
public ResponseEntity<String> handleRawRequest(HttpServletRequest request) throws IOException {
    // 1. 獲取請求體字符串
    StringBuilder sb = new StringBuilder();
    try (BufferedReader reader = request.getReader()) {
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
    }
    String requestBody = sb.toString(); // 完整原始請求體 (JSON, XML, 純文本等)

    // 2. 業務處理...
    String responseBody = process(requestBody);

    // 3. 返回
    return ResponseEntity.ok()
            .contentType(MediaType.APPLICATION_JSON)
            .body(responseBody);
}

關鍵點

  • `request.getReader()` 返回 `BufferedReader`,按請求編碼 (默認 ISO-8859-1,需配合 `CharacterEncodingFilter` 設置 UTF-8) 解碼。
  • `request.getInputStream()` 返回原始字節流 `ServletInputStream`,適合二進制數據或自定義解碼。
  • 流只能讀一次!若前面有 Filter/Interceptor 讀過流,這裡會讀空。解決:使用 `ContentCachingRequestWrapper` 包裝請求 (Spring 提供)。

獲取響應原始字符串 (Response Body)

需攔截響應寫入,使用 `ContentCachingResponseWrapper`:

@Component
public class ResponseLoggingFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(request);
        ContentCachingResponseWrapper wrappedResponse = new ContentCachingResponseWrapper(response);

        try {
            filterChain.doFilter(wrappedRequest, wrappedResponse);
        } finally {
            // 請求體
            String reqBody = new String(wrappedRequest.getContentAsByteArray(), StandardCharsets.UTF_8);
            // 響應體 (需調用 copyBodyToResponse 才能獲取)
            String respBody = new String(wrappedResponse.getContentAsByteArray(), StandardCharsets.UTF_8);

            log.info("Request: {} {}", request.getMethod(), request.getRequestURI());
            log.info("Request Body: {}", reqBody);
            log.info("Response Body: {}", respBody);

            wrappedResponse.copyBodyToResponse(); // 關鍵:將緩存的響應寫回真實響應流
        }
    }
}

Spring Boot 3 / Servlet 6 簡化

Spring Boot 3.0+ 基於 Servlet 6.0,`HttpServletRequest` 內置了 `getInputStream()` 可重複讀取 (需容器支持),但最穩健仍用 `ContentCachingRequestWrapper`。

常見誤區

「我不是要獲得參數,我是要獲得純字符串... 直接在參數裡面寫 request, getInputStream() 就可以了」—— 這是正確的直覺,但要注意流的一次性讀取限制和編碼設置。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved