如果在拦截器或过滤器中读取请求参数的流,就会导致在controller里无法解析参数,因为request.getInputStream()只能读取一次的问题 , 使用下面的方法:流可重复读
示例中在拦截器中,打印入参。
/***
* @date 2023-12-12
* @decription HttpServletRequest 包装器
* 解决: request.getInputStream()只能读取一次的问题
* 目标: 流可重复读
*/
@Slf4j
public class RequestWrapper extends HttpServletRequestWrapper {
/**
* 日志
*/
private static final Logger logger = LoggerFactory.getLogger(RequestWrapper.class);
/**
* 请求体
*/
private final String body;
public RequestWrapper(HttpServletRequest request) {
super(request);
body = getBody(request);
}
/**
* 获取请求体
* @param request 请求
* @return 请求体
*/
private String getBody(HttpServletRequest request) {
try {
byte[] bodyBytes = StreamUtils.copyToByteArray(request.getInputStream());
return new String(bodyBytes, request.getCharacterEncoding());
} catch (IOException e) {
logger.debug(e.getMessage());
throw new RuntimeException(e);
}
}
/**
* 获取请求体
* @return 请求体
*/
public String getBody() {
return body;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() throws IOException {
// 创建字节数组输入流
final ByteArrayInputStream stream = new ByteArrayInputStream(body.getBytes(Charset.defaultCharset()));
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() {
return stream.read();
}
};
}
}
示例:
@Slf4j
@Component
public class PrintLogInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (StrUtil.equalsIgnoreCase(request.getMethod(), HttpMethod.POST.name())) {
String body = new RequestWrapper(request).getBody();
log.info("请求POST参体:{}", body);
}
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}