在我的 Web 服务应用程序中,我有一个请求对象,它是 HttpServletRequest 的一个实例。问题是某些客户端(客户)在正文中发送了一些无效的请求,我想记录它。在我的日志记录类中,我引用了请求对象,但是使用下面的函数我得到了“StreamClosed”异常。我认为这是因为 Jackson 已经消耗了该流并在其 json 反序列化过程中关闭了它。
所以我的问题是,如果请求正文无效,如何安全地记录该请求正文?显然,在 jackson 尝试反序列化它之前我无法预先记录它,因为这会篡改输入流。
public static String getBody(HttpServletRequest request) throws IOException {
String body = null;
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
throw ex;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
throw ex;
}
}
}
body = stringBuilder.toString();
return body;
}
最佳答案
创建一个过滤器,将请求包装在一个对象中,该对象允许多次检索 InputStream。
一个简单的请求包装器实现将执行以下操作:
- 将原始Request的InputStream读取到byte[]中,然后关闭它。
- 每次调用(包装器的)getInputStream() 方法时,都会创建并返回一个新的 ByteArrayInputStream。
关于java - 如何在不干扰主逻辑的情况下安全地记录来自 HttpServletRequest 的请求正文?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45866923/