Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从HttpServletRequest安全地记录请求主体而不干扰主逻辑?_Java_Jackson - Fatal编程技术网

Java 如何从HttpServletRequest安全地记录请求主体而不干扰主逻辑?

Java 如何从HttpServletRequest安全地记录请求主体而不干扰主逻辑?,java,jackson,Java,Jackson,在我的Web服务应用程序中,我有一个请求对象,它是HttpServletRequest的一个实例。问题是一些客户端(客户)在正文中发送了一些无效的请求,我想记录它。在我的日志类中,我有对请求对象的引用,但是使用下面的函数,我得到了一个“StreamClosed”异常。我认为这是因为Jackson已经使用了这个流,并在json反序列化过程中关闭了它 所以我的问题是,如果请求主体无效,我如何安全地记录它?显然,在Jackson尝试反序列化它之前,我不能预先记录它,因为那样会篡改输入流

在我的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的对象中

简单的请求包装器实现将执行以下操作:

  • 将原始请求的InputStream读入字节[],然后关闭它
  • 每次调用(包装器的)getInputStream()方法时,创建并返回一个新的ByteArrayInputStream

  • 我可能建议尝试使用专用库记录请求,请查看: