java HttpServletRequestWrapper getinputsteam 和getparameter 同时使用拿不到值

问题是这样的,后台接口要进行xss过滤,然后我加了一个过滤器

public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
    
    private byte[] cachedBytes;
    
    private HttpServletRequest request;
    
    public XssHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        this.request=request;
    }
    
    @Override
    public ServletInputStream getInputStream() throws IOException {
        if (null == this.cachedBytes) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            IOUtils.copy(request.getInputStream(), baos);
            this.cachedBytes = baos.toByteArray();
        }
        final ByteArrayInputStream bais = new ByteArrayInputStream(cachedBytes);
        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 bais.read();
            }
        };
    }
    
    @Override
    public BufferedReader getReader() throws IOException{
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }
    
    @Override
    public String getParameter(String name) {
        String value = super.getParameter(replaceXSS(name));
        if (value != null) {
            value = replaceXSS(value);
        }
        return value;
    }
    
    @Override
    public String[] getParameterValues(String name) {
        String[] values = super.getParameterValues(replaceXSS(name));
        if (values != null && values.length > 0) {
            for (int i = 0; i < values.length; i++) {
                values[i] = replaceXSS(values[i]);
            }
        }
        return values;
    }
    
    @Override
    public String getHeader(String name) {
        
        String value = super.getHeader(replaceXSS(name));
        if (value != null) {
            value = replaceXSS(value);
        }
        return value;
    }
    
    /**
     * 去除待带script、src的语句,转义替换后的value值
     */
    public static String replaceXSS(String value) {
        if (value != null) {
            value = value.replaceAll("<script>", "&lt;script&gt;");
            value = value.replaceAll("</script>", "&lt;/script&gt;");
            return value;
        }
        return value;
    }
    
}

然后又加了一个拦截器,这个拦截器是计算请求签名的,需要计算请求体的md5,我采用 request.getInputstream 拿到流,这一步是没有问题
最后进入控制的时候,发现拿不到值了,控制器是这样的

 @PostMapping(value = "/get")
    public ResponseEntity get( Student student) throws IOException {
        return ResponseUtil.ok(student,"获取成功"); // student 是空的  request.getprameter 也拿不到值
    }

请求的数据格式为 Content-Type application/x-www-form-urlencoded

img

网上说getinputstream 和getparameter 是冲突的,请问有办法解决吗

最简单的方式是在 XssHttpServletRequestWrapper 类中提供获取字节数组的方法,然后在拦截器中强转 ServletRequest 类型为 XssHttpServletRequestWrapper ,然后再调用获取字节数组的方法

这个获取的是流,获取完了之后就没有了
肯定在控制层拿不到呀

调用完getInputStream之后,往后传的得是XssHttpServletRequestWrapper。
也就是chain.doFilter(new XssHttpServletRequestWrapper(httpServletRequest), response);