最近在做请求鉴权的时候拦截器中需要获取post请求参数,所以获取了多次request中的数据so 总结一下,顺便避免大家踩坑。
总结为:
1.最好继承rHttpServletRequestWrapper重写request
2.通过工具方法获取post数据,一定要传入重写的request而不是原生的
如果:
上图中的get请求获取参数这里不做解释,很好理解,直接获取即可。而post请求这里提供了一个方法,用来获取post请求参数以JSONObject返回,这里用到的JSONObject为fastjson包中,大家自己导入依赖即可,代码自取如下:
/**
* 获取post请求参数以JSONObject返回
* @param wrapper
* @return JSONObject
*/
private JSONObject getPostParm(BodyReaderHttpServletRequestWrapper wrapper) {
StringBuffer jb = new StringBuffer();
String line = null;
try {
BufferedReader reader = wrapper.getReader();
while ((line = reader.readLine()) != null) {
jb.append(line);
}
JSONObject jsonObject= JSONObject.parseObject(jb.toString());//转化成json对象
return jsonObject;
} catch (Exception e) {
throw new RuntimeException("Error parsing JSON request string ",e);
}
}
这里传入的是一个BodyReaderHttpServletRequestWrapper,就是先将RequestBody保存为一个byte数组,然后通过Servlet自带的HttpServletRequestWrapper类覆盖getReader()和getInputStream()方法,使流从保存的byte数组读取。然后最重要的在Filter中将ServletRequest替换为BodyReaderHttpServletRequestWrapper,代码如下:一定要记得替换,不然还是会出现request读取二次的问题
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
private final byte[] body;
public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
BufferedReader reader = request.getReader();
body = 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 listener) {
}
@Override
public int read() throws IOException {
return bais.read();
}
};
}
/**
* 通过BufferedReader和字符编码集转换成byte数组
* @param br
* @param encoding
* @return
* @throws IOException
*/
private byte[] readBytes(BufferedReader br,String encoding) throws IOException{
String str = null,retStr="";
while ((str = br.readLine()) != null) {
retStr += str;
}
if (StringUtils.isNotBlank(retStr)) {
return retStr.getBytes(Charset.forName(encoding));
}
return null;
}
}