由于在SpringBoot过滤器或者拦截器中,request中getReader()和getInputStream()只能调用一次,到controller里数据就为空了,因此会导致Controller中@RequestBody的参数无法注入而导致 400 错误
写HttpServletRequestWrapper把request保存下来,然后通过过滤器把保存下来的request再填充进去
- @Component
- public class CxmHttpServletRequestWrapper extends HttpServletRequestWrapper {
-
- private byte[] requestBody = new byte[0];
- private boolean bufferFilled = false;
-
- private ConcurrentHashMap<String, String> cxmHeaders = new ConcurrentHashMap<>();
-
- public CxmHttpServletRequestWrapper(HttpServletRequest request) {
- super(request);
- }
-
- @Override
- public ServletInputStream getInputStream() throws IOException {
- return new CachedServletInputStream(getRequestBody());
- }
-
- @Override
- public String getHeader(String name) {
- String headerValue = cxmHeaders.get(name);
- if (headerValue != null) {
- return headerValue;
- } else {
- return super.getHeader(name);
- }
- }
-
- public void setHeader(String name, String value){
- this.cxmHeaders.put(name, value);
- }
-
- public byte[] getRequestBody() throws IOException {
- if (bufferFilled) {
- return Arrays.copyOf(requestBody, requestBody.length);
- }
- InputStream inputStream = super.getInputStream();
- requestBody = IOUtils.toByteArray(inputStream);
- bufferFilled = true;
- return requestBody;
- }
- }
写一个CachedServletInputStream继承ServletInputStream用来处理数据
- public class CachedServletInputStream extends ServletInputStream {
-
- private ByteArrayInputStream buffer;
-
- public CachedServletInputStream(byte[] contents) {
- this.buffer = new ByteArrayInputStream(contents);
- }
-
- @Override
- public int read() throws IOException {
- return buffer.read();
- }
-
- @Override
- public boolean isFinished() {
- return buffer.available() == 0;
- }
-
- @Override
- public boolean isReady() {
- return true;
- }
-
- @Override
- public void setReadListener(ReadListener listener) {
- throw new RuntimeException("Not implemented");
- }
- }
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
- throws IOException, ServletException {
- HttpServletRequest requestWrapper = null;
- if (request instanceof HttpServletRequest) {
- requestWrapper = new CxmHttpServletRequestWrapper((HttpServletRequest) request);
- }
-
- chain.doFilter(requestWrapper, response);
-
- }
- @Slf4j
- @Configuration
- public class WebMvcConfig implements WebMvcConfigurer {
-
- /**
- *
- * @Title: Filters
- * @Description: 配置自定义的filter
- * @return
- * @throws
- *
- */
- @Bean
- public FilterRegistrationBean<CxmRequestValidFilter> Filters() {
- FilterRegistrationBean<CxmRequestValidFilter> register = new FilterRegistrationBean<CxmRequestValidFilter>();
- register.setFilter(new CxmRequestValidFilter());
- register.addUrlPatterns("/*");
- // 初始化filter的参数
-
- register.addInitParameter("profile", profile);
-
- register.setName("cxmRequestValidFilter");
- return register;
- }
-
-
- }