在代码编写过程中,我们使用拦截器做通用的业务拦截处理。但通过request.getInputStream()获取了后,再到Controller层就获取不到流了。本文对此问题处理过程如下。
第一步:先创建自定义CustomRequestWrapper
import jodd.io.StreamUtil;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class CustomRequestWrapper extends HttpServletRequestWrapper {
private byte[] body;
public CustomRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
body = StreamUtil.readBytes(request.getReader(), "UTF-8");
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() throws IOException {
return bais.read();
}
};
}
public byte[] getBody() {
return body;
}
public void setBody(byte[] body) {
this.body = body;
}
}
第二步:创建过滤器ChannelFilter,目的是将流再传递
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@WebFilter(urlPatterns = "
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
ServletRequest requestWrapper = null;
if(servletRequest instanceof HttpServletRequest) {
requestWrapper = new CustomRequestWrapper((HttpServletRequest) servletRequest);
}
if(requestWrapper == null) {
filterChain.doFilter(servletRequest, servletResponse);
} else {
filterChain.doFilter(requestWrapper, servletResponse);
}
}
@Override
public void destroy() {
}
}
注意,这里springboot要启动拦截器功能
@Configuration
@EnableScheduling
@ServletComponentScan
@ComponentScan
public class ApplicationConfig {
}
第三步:使用自定义CustomRequestWrapper
// POST请求通过流获取参数 CustomRequestWrapper requestWrapper = new CustomRequestWrapper(request); String body = new String(requestWrapper.getBody(), StandardCharsets.UTF_8);
小细节:这里的请求方式一定是POST,小坑勿踩
补充一下,通过request获取参数时,根据GET和POST请求的方式不一样
Map paramMap = Maps.newTreeMap();
if(Constants.GET.equals(request.getMethod())){
// GET请求直接获取
Enumeration parameterNames = request.getParameterNames();
if(parameterNames.hasMoreElements()){
String key = parameterNames.nextElement();
String value = request.getParameter(key);
paramMap.put(key, value);
}
}
if(Constants.POST.equals(request.getMethod())){
// POST请求通过流获取参数
CustomRequestWrapper requestWrapper = new CustomRequestWrapper(request);
String body = new String(requestWrapper.getBody(), StandardCharsets.UTF_8);
if(StringUtils.isNotBlank(body)){
paramMap = JsonUtils.jsonToPojo(body, Map.class);
}
}



