在代码编写过程中,我们使用拦截器做通用的业务拦截处理。但通过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请求直接获取 EnumerationparameterNames = 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); } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)