Java 记录通过InputStream的所有内容

Java 记录通过InputStream的所有内容,java,json,gson,inputstream,Java,Json,Gson,Inputstream,我使用Gson来处理Json响应。有时我会遇到异常,但不幸的是,我没有足够的上下文来确定问题的确切位置 JsonReader的创建如下所示: private JsonReader getJsonReader(final HttpEntity entity) throws IOException { final InputStreamReader reader = new InputStreamReader(entity.getContent(), StandardCharsets.UTF

我使用Gson来处理Json响应。有时我会遇到异常,但不幸的是,我没有足够的上下文来确定问题的确切位置

JsonReader的创建如下所示:

private JsonReader getJsonReader(final HttpEntity entity) throws IOException {
    final InputStreamReader reader = new InputStreamReader(entity.getContent(), StandardCharsets.UTF_8);
    return new JsonReader(reader);
}
我的想法是将
InputStreamReader
子类化,并记录所有经过它的内容,以便在抛出异常时有更多的上下文


有更好的方法吗?

我创建了以下两个子类:

public class LoggingReader extends InputStreamReader {

    private char[] lastRead;

    public LoggingReader(final InputStream inputStream, final Charset charset) {
        super(inputStream, charset);
    }

    @Override
    public int read(final char[] chars, final int i, final int i1) throws IOException {
        final int result = super.read(chars, i, i1);
        lastRead = chars;
        return result;
    }

    public String getLastRead() {
        return new String(lastRead);
    }
}

public class LoggingJsonReader extends JsonReader {
    private final LoggingReader reader;
    public LoggingJsonReader(final LoggingReader in) {
        super(in);
        this.reader = in;
    }

    public String getLastRead() {
        return reader.getLastRead();
    }
}
现在,当抛出异常时,我会:

catch (Exception ex) {
  if (reader instanceof LoggingJsonReader) {
    LoggingJsonReader lReader = (LoggingJsonReader) reader;
    log.error(lReader.getLastRead());
  }

我创建了以下两个子类:

public class LoggingReader extends InputStreamReader {

    private char[] lastRead;

    public LoggingReader(final InputStream inputStream, final Charset charset) {
        super(inputStream, charset);
    }

    @Override
    public int read(final char[] chars, final int i, final int i1) throws IOException {
        final int result = super.read(chars, i, i1);
        lastRead = chars;
        return result;
    }

    public String getLastRead() {
        return new String(lastRead);
    }
}

public class LoggingJsonReader extends JsonReader {
    private final LoggingReader reader;
    public LoggingJsonReader(final LoggingReader in) {
        super(in);
        this.reader = in;
    }

    public String getLastRead() {
        return reader.getLastRead();
    }
}
现在,当抛出异常时,我会:

catch (Exception ex) {
  if (reader instanceof LoggingJsonReader) {
    LoggingJsonReader lReader = (LoggingJsonReader) reader;
    log.error(lReader.getLastRead());
  }

“更好”是一个非常模糊的术语。我认为你的想法是合理的:应该很容易实施;并且不需要对代码库进行任何“戏剧性”的更改。异常通常应该包含足够的上下文(Jackson异常在这方面肯定从未让我失望)。我想这将取决于框架。子类化
InputStream
或简单地使用调试器应该可以解决问题。1)
JsonReader.toString()
输出当前解析位置。这是一个好的背景吗?2) 如果有必要,我将子类化
JsonReader
,而不是
InputStreamReader
JsonReader
通过设计去除多余的令牌。(假设一个漂亮的打印/格式化输入流记录了所有空格,而装饰的
JsonReader
只记录JSON标记)。@Roland嗯,这取决于您期望的上下文是什么。:)我也曾想过将
读取器
子类化(但实际上并非
InputStreamReader
支持装饰),但由于您更关注Gson的内容,因此我将实现类似于
JsonReader
的子类的东西,其中包含一小队最后的标记,这些标记可能具有各自的值。是的,实现起来有点困难,但它肯定会剥离空白,等等。不过,您可能还希望跟踪
LoggingReader
中的位置(读取的字节总数),以便更准确地定位无效的JSON。“更好”是一个非常模糊的术语。我认为你的想法是合理的:应该很容易实施;并且不需要对代码库进行任何“戏剧性”的更改。异常通常应该包含足够的上下文(Jackson异常在这方面肯定从未让我失望)。我想这将取决于框架。子类化
InputStream
或简单地使用调试器应该可以解决问题。1)
JsonReader.toString()
输出当前解析位置。这是一个好的背景吗?2) 如果有必要,我将子类化
JsonReader
,而不是
InputStreamReader
JsonReader
通过设计去除多余的令牌。(假设一个漂亮的打印/格式化输入流记录了所有空格,而装饰的
JsonReader
只记录JSON标记)。@Roland嗯,这取决于您期望的上下文是什么。:)我也曾想过将
读取器
子类化(但实际上并非
InputStreamReader
支持装饰),但由于您更关注Gson的内容,因此我将实现类似于
JsonReader
的子类的东西,其中包含一小队最后的标记,这些标记可能具有各自的值。是的,实现起来有点困难,但它肯定会剥离空白,等等。不过,您可能还希望跟踪
LoggingReader
中的位置(读取的字节总数),以便更准确地定位无效的JSON。