问题是这样的,后台接口要进行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>", "<script>");
value = value.replaceAll("</script>", "</script>");
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
网上说getinputstream 和getparameter 是冲突的,请问有办法解决吗
最简单的方式是在 XssHttpServletRequestWrapper 类中提供获取字节数组的方法,然后在拦截器中强转 ServletRequest 类型为 XssHttpServletRequestWrapper ,然后再调用获取字节数组的方法
这个获取的是流,获取完了之后就没有了
肯定在控制层拿不到呀
调用完getInputStream之后,往后传的得是XssHttpServletRequestWrapper。
也就是chain.doFilter(new XssHttpServletRequestWrapper(httpServletRequest), response);