因为spring已经读取过一次输入流,所以手动用getInputStream()获取到的值为空,解决方法
1.新建wrapper继承HttpServletRequestWrapper如下
import org.springframework.web.bind.annotation.RequestMethod; import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.io.*; import java.util.Arrays; import java.util.Objects; import java.util.stream.Collectors; public class InputStreamHttpServletRequestWrapper extends HttpServletRequestWrapper { private final byte[] streamBody; private static final int BUFFER_SIZE = 4096; /** * Constructs a request object wrapping the given request. * * @param request The request to wrap * @throws IllegalArgumentException if the request is null */ public InputStreamHttpServletRequestWrapper(HttpServletRequest request) throws IOException { super(request); byte[] bytes = new byte[0]; String uri = request.getRequestURI(); if (Objects.isNull(request.getHeader("Content-Type")) || request.getHeader("Content-Type").contains("multipart/form-data;")) { bytes = inputStream2Byte(request.getInputStream()); } else if (isFormPost(request)) { // 从ParameterMap获取参数,并保存以便多次获取 bytes = params2Byte(request); //bytes = inputStream2Byte(request.getInputStream()); } else { bytes = inputStream2Byte(request.getInputStream()); } streamBody = bytes; } private boolean isFormPost(HttpServletRequest request) { return RequestMethod.POST.name().equals(request.getMethod()); } private byte[] params2Byte(HttpServletRequest request) { byte[] bytes = request.getParameterMap().entrySet().stream().map(entry -> { String result; String[] value = entry.getValue(); if (value != null && value.length > 1) { result = Arrays.stream(value).map(s -> entry.getKey() + "=" + s).collect(Collectors.joining("&")); } else { result = entry.getKey() + "=" + value[0]; } return result; }).collect(Collectors.joining("&")).getBytes(); return bytes; } private byte[] inputStream2Byte(InputStream inputStream) throws IOException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); byte[] bytes = new byte[BUFFER_SIZE]; int length; while ((length = inputStream.read(bytes, 0, BUFFER_SIZE)) != -1) { outputStream.write(bytes, 0, length); } return outputStream.toByteArray(); } @Override public ServletInputStream getInputStream() throws IOException { ByteArrayInputStream inputStream = new ByteArrayInputStream(streamBody); return new ServletInputStream() { @Override public boolean isFinished() { return false; } @Override public boolean isReady() { return false; } @Override public void setReadListener(ReadListener listener) { } @Override public int read() throws IOException { return inputStream.read(); } }; } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream())); } }
2.新建filter
import org.springframework.web.filter.HiddenHttpMethodFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class InputStreamWrapperFilter extends HiddenHttpMethodFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { ServletRequest servletRequest = new InputStreamHttpServletRequestWrapper(request); filterChain.doFilter(servletRequest, response); } }
3.新建config配置监听
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.web.filter.HiddenHttpMethodFilter; @Configuration public class RequestConfig { @Bean @Order(1) public HiddenHttpMethodFilter hiddenHttpMethodFilter() { return new InputStreamWrapperFilter(); } }