springboot 在controller層獲取Post請求中request.getInputStream的值


springboot 在controller層獲取Post請求中request.getInputStream的值
https://www.csdn.net/tags/Mtjacg1sMTYyOTAtYmxvZwO0O0OO0O0O.html

  這個有點坑,首先request的流的獲取每個請求只能獲取一次,之后再通過getInputStream獲取流的時候就獲取不到數據了,還有getInputStream和getReader和getParameter都可以獲取輸入流數據,但是存在沖突,也就是三者只要有一個對request獲取了輸入流信息,那么其他的方法之后就獲取不到數據了。這就是springboot埋的一個小坑,那么怎么通過request獲得Post請求的body值呢?

首先直接在controller層直接寫肯定是獲取不到的,即使你自己覺得你是第一次獲取輸入流,其實不然,在springboot啟動的時候攔截器中也通過getParameter獲取過輸入流,導致后面沒辦法獲取輸入流

下面解決辦法:重寫HiddenHttpMethodFilter攔截器

我們先看下這個攔截器里面的方法

  
  
  
          

   
   
   
           
  1. @Override
  2. protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
  3. throws ServletException, IOException {
  4. HttpServletRequest requestToUse = request;
  5. if ( "POST".equals( request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {
  6. String paramValue = request.getParameter(this.methodParam);
  7. if (StringUtils.hasLength(paramValue)) {
  8. requestToUse = new HttpMethodRequestWrapper( request, paramValue);
  9. }
  10. }
  11. filterChain. do Filter(requestToUse, response);
  12. }

這個request.getParameter()看到了吧,就是它影響了后面獲取輸入流,我們自己重寫這個方法就好了,我自己是在這個重寫的方法里將request的輸入流獲取然后直接用的,我貼下代碼


   
   
   
           
  1. import com.alibaba.fastjson.JSON;
  2. import lombok.extern.slf4j.Slf4j;
  3. import net.sf.json.JSONObject;
  4. import org.springframework.boot.web.filter.OrderedHiddenHttpMethodFilter;
  5. import org.springframework.context.annotation.Bean;
  6. import org.springframework.context.annotation.Configuration;
  7. import org.springframework.web.filter.HiddenHttpMethodFilter;
  8. import javax.servlet.FilterChain;
  9. import javax.servlet.ServletException;
  10. import javax.servlet.ServletInputStream;
  11. import javax.servlet.http.HttpServletRequest;
  12. import javax.servlet.http.HttpServletResponse;
  13. import java.io.BufferedReader;
  14. import java.io.IOException;
  15. import java.io.InputStreamReader;
  16. @Slf4j
  17. @Configuration
  18. public class WebConfig {
  19. @Bean
  20. public HiddenHttpMethodFilter hiddenHttpMethodFilter () {
  21. return new OrderedHiddenHttpMethodFilter() {
  22. @Override
  23. protected void doFilterInternal (HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
  24. throws ServletException, IOException {
  25. BufferedReader reader = new BufferedReader(
  26. new InputStreamReader(request.getInputStream(), "UTF-8"));
  27. String line;
  28. String result = "";
  29. while ((line = reader.readLine()) != null) {
  30. result += line;
  31. }
  32. log.info( "業務驗證提示信息! URL={} 參數:{}", request.getRequestURL().toString(),JSON.toJSON(result));
  33. filterChain.doFilter(request, response);
  34. }
  35. };
  36. }
  37. }

然后我說一下這個坑:

一:即使重寫的方法我們不用輸入流,再controller也沒辦法獲取post的輸入流,我自己測了好多次都是這樣,具體情況不清楚

二:即使將獲取的輸入流裝入session中,在controller中獲取session也會出錯,獲取不到值

三:關注我關注我

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

經過我的測試,我們發現這樣雖然能夠取到post輸入流,但是這樣之后cotroller用於接參的對象將取不到數據,會報request body is missing.那么大家就別用這種方式取輸入流吧,通過aop去獲取輸入參數也應該行,我沒試過,但思路是對的!!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM