sunny123456

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  1796 随笔 :: 22 文章 :: 24 评论 :: 226万 阅读
< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5

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拦截器

我们先看下这个拦截器里面的方法
@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
 
		HttpServletRequest requestToUse = request;
 
		if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {
			String paramValue = request.getParameter(this.methodParam);
			if (StringUtils.hasLength(paramValue)) {
				requestToUse = new HttpMethodRequestWrapper(request, paramValue);
			}
		}
 
		filterChain.doFilter(requestToUse, response);
	}

这个request.getParameter()看到了吧,就是它影响了后面获取输入流,我们自己重写这个方法就好了,我自己是在这个重写的方法里将request的输入流获取然后直接用的,我贴下代码

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.springframework.boot.web.filter.OrderedHiddenHttpMethodFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.HiddenHttpMethodFilter;
 
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
 
@Slf4j
@Configuration
public class WebConfig {
    @Bean
    public HiddenHttpMethodFilter hiddenHttpMethodFilter() {
        return new OrderedHiddenHttpMethodFilter() {
            @Override
            protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
                    throws ServletException, IOException {
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(request.getInputStream(), "UTF-8"));
                String line;
                String result = "";
                while ((line = reader.readLine()) != null) {
                    result += line;
                }
                log.info("业务验证提示信息! URL={} 参数:{}", request.getRequestURL().toString(),JSON.toJSON(result));
                filterChain.doFilter(request, response);
            }
        };
    }
}

然后我说一下这个坑:

一:即使重写的方法我们不用输入流,再controller也没办法获取post的输入流,我自己测了好多次都是这样,具体情况不清楚

二:即使将获取的输入流装入session中,在controller中获取session也会出错,获取不到值

三:关注我关注我

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

经过我的测试,我们发现这样虽然能够取到post输入流,但是这样之后cotroller用于接参的对象将取不到数据,会报request body is missing.那么大家就别用这种方式取输入流吧,通过aop去获取输入参数也应该行,我没试过,但思路是对的!!!!

posted on   sunny123456  阅读(792)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示