java - Java 中反复无常的 Json 解析错误

标签 java json wget

我有一个 Java 服务器应用程序,带有解析 Json 的端点。 我像这样用 Wget 发出请求,

wget --header="Content-Type: application/json" --post-file=somefile.json %SERVER_URL%

文件是这样解析的,

InputStream in = httpExchange.getRequestBody();
JsonReader reader = Json.createReader(in);

当 json 文件很大(大约 10,000 行)时,Create reader 有时会抛出异常,但对于同一个文件有时会成功。错误消息如下所示,

Unexpected char -1 at (line no=4029, column no=228, offset=204873)

如果我转到文件中的该行,它看起来很好。我还尝试用 Javascript 解析文件,只需在文件开头添加 'var a = ' 就可以了。我尝试过将文件一分为二,但后来我意识到,随着文件变小,无论内容如何,​​它有时都会成功......

是否是 Java 在 wget 完全发布文件之前就开始流式传输文件或类似的奇怪事情?解析器会看到过早的 EOF 或其他东西......

无能:(

编辑:

我首先使用此函数将文件保存到字符串中,

static String convertStreamToString(java.io.InputStream is) {
    java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
    return s.hasNext() ? s.next() : "";
}

然后我用这个替换了 JsonReader 创建,

InputStream in = he.getRequestBody();
String reqBodyString = convertStreamToString(in);
JsonReader reader = Json.createReader(new StringReader(reqBodyString));

使用 NetBeans,我将 reqBodyString 的值保存到文件中,并且该文件提前结束。看来我没有得到整个 body ...一定是某些东西关闭流太快了...? :(

最佳答案

这些错误是由于客户端在服务器仍在读取流时过快完成连接而引起的。

HttpExchange 返回固定长度输入流。在调试器中,我可以看到流的私有(private)成员“剩余”仍然是 +100KB,尽管显然它已经完成读取。作为引用,这里是 FixedLengthInputStream 的实现。

我已将此消息添加到服务器,

        try{
            JsonReader reader = Json.createReader(in);
            // ... do stuff
        }
        catch(JsonParsingException exception) {
            String msg = "JsonParsingException: " + exception.getLocalizedMessage();
            msg += " (could be caused by a premature EOF if the client timed out too quickly)";
            logMessage(msg);                
        }

客户端的解决方案是增加超时,

wget --timeout=30 ...

但是,这在 Windows 的 wget 中似乎不起作用,

> wget64 --version
GNU Wget 1.17.1 built on mingw32.

我在 cygwin 上安装了 wget,即使没有超时参数,它也能工作,

$ wget --version
GNU Wget 1.18 built on cygwin.

关于java - Java 中反复无常的 Json 解析错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41367174/

相关文章:

javascript - 如何通过具有未知父名称的二级属性过滤json?

wget - -nc 选项是否跳过下载现有文件?

curl - 将 cURL 与两个匹配范围结合使用

multithreading - 多个wget -r同时访问一个站点?

java - 使用 Gson 从 JSON 对象获取键名

java - 在 Play 2.3.7 上从 Promise<JsonNode> 检索 HTTP 状态

javascript - 获取json数组值并通过jquery将其放入单独的div中

java - 将 Spring MVC 投影与 JSON 和 Jackson 结合使用

java - 如何将数据添加到按钮表单中的另一个 Activity

php - 从存储的相对路径从mysql php获取图像的绝对路径