<!--一个博主专栏付费入口结束-->
<link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-d284373521.css">
<link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-d284373521.css">
<div class="htmledit_views" id="content_views">
<h3> 这个有点坑,首先request的流的获取每个请求只能获取一次,之后再通过getInputStream获取流的时候就获取不到数据了,还有getInputStream和getReader和getParameter都可以获取输入流数据,但是存在冲突,也就是三者只要有一个对request获取了输入流信息,那么其他的方法之后就获取不到数据了。这就是springboot埋的一个小坑,那么怎么通过request获得Post请求的body值呢?</h3>
首先直接在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去获取输入参数也应该行,我没试过,但思路是对的!!!!