继承HttpServletRequestWrapper实现流重复读、参数过滤等场景
程序员文章站
2022-04-01 10:38:36
背景 项目基于springboot开发,RestFull接口向外暴露的API需要进行签名验证,即在进入真正controller方法前,需要先验证接口请求的有效性,所以需要对提交的POST流进行JSON读,并将相关参数进行验签。如果在Filter中使用request.getInputStream()来获取流来得到body中的信息,可以达到预期效果,但是流的获取只能获取一次,之后再获取就获取不到了,导致controller无法拿到参数而报错。参考相关资料发现实现一个类继承HttpServletReques...
背景
项目基于springboot开发,RestFull接口向外暴露的API需要进行签名验证,即在进入真正controller方法前,需要先验证接口请求的有效性,所以需要对提交的POST流进行JSON读,并将相关参数进行验签。如果在Filter中使用request.getInputStream()来获取流来得到body中的信息,可以达到预期效果,但是流的获取只能获取一次,之后再获取就获取不到了,导致controller无法拿到参数而报错。参考相关资料发现实现一个类继承HttpServletRequestWrapper,重写其中的getInputStream方法,让其可以重复获取我们想要的流。
自定义RequestWrapper类
package com.argrace.platform.interceptor;
import com.argrace.platform.exception.VeecloudBizException;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RequestWrapper extends HttpServletRequestWrapper {
private static final Logger log = LoggerFactory.getLogger(RequestWrapper.class);
private String mBody;
public RequestWrapper(HttpServletRequest request) {
super(request);
this.mBody = this.getBody(request);
}
public static String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
try {
String line;
try {
while((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException var13) {
log.error("IOException", var13);
}
} finally {
try {
is.close();
} catch (IOException var12) {
log.error("IOException", var12);
}
}
return sb.toString();
}
private String getBody(HttpServletRequest request) {
try {
return convertStreamToString(request.getInputStream());
} catch (IOException var3) {
log.debug(var3.getMessage());
throw new VeecloudBizException(var3);
}
}
public String getBody() {
return this.mBody;
}
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream bais = new ByteArrayInputStream(this.mBody.getBytes(Charset.defaultCharset()));
return new ServletInputStream() {
public boolean isFinished() {
return false;
}
public boolean isReady() {
return false;
}
public void setReadListener(ReadListener readListener) {
}
public int read() throws IOException {
return bais.read();
}
};
}
}
实用案例
代码块:
public void test(HttpServletRequest request, HttpServletResponse response) throws Exception {
String param;
if (this.isJson(request)) {
param = (new RequestWrapper(request)).getBody();
log.info("[test] 获取到application/json请求参数 : {}", param);
} else {
SortedMap<String, String> map = this.getAllParams(request);
param = JSON.toJSONString(map);
log.info("[test] 获取到application/x-www-form-urlencoded请求参数 : {}", param);
}
}
private boolean isJson(HttpServletRequest request) {
if (request.getContentType() == null) {
return false;
} else {
return request.getContentType().equals("application/json") || request.getContentType().equals("application/json;charset=UTF-8");
}
}
本文地址:https://blog.csdn.net/keyingbo2008/article/details/107684691
上一篇: 如何将虾米音乐的歌单导入QQ音乐?
下一篇: Oracle游标使用参考语句实例解析