httpclient提交json到tomcat,接收到的json却是不完整的

发布于 2021-12-08 23:41:19 字数 724 浏览 818 评论 12

写了一个rest接口,接口接受json数据解析批量入索引。入索引的频率和大都挺大的,每天看日志都会有几条写入失败,原因是收到client端的数据不完整,是一个被截断的json。如图:

我是通过httprequest的getInputStream自己解析的,解析出来就成这个样子了。长度我也记录了一下,65k多,不可能是超过tomcat接受post请求体大小限制导致的,maxPostSize我配置了50M。

客户端使用httpclient传输的,一开始担心是客户端的问题,我在客户端做了json校验,但凡客户端不是json格式直接返回失败抛出异常,但是产生这条日志的时候,客户端并没有抛异常。而且客户端是把json字符串封装成一个实体作为api,然后再反序列化成字符串传输的,如果是使用者字符串拼的有问题,肯定会在前端先报错。

那么问题就集中在服务端了,到底还有什么限制会导致服务端接受数据不全吗?我还想到一种可能,就是数据再到达我这里的时候中间经历过三次json序列化和反序列化:业务数据序列化成埋点json字符串,消费端接受mq中埋点信息反序列化成实体,通过client api序列化成json字符串传输到tomcat,几次解析都使用fastjson,所以会不会是几次解析使用的版本不一样导致的呢?tomcat用的1.2.7  client用的1.2.9

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

最偏执的依靠 2021-12-09 15:39:51

解决了吗?坐等结果

顾忌 2021-12-09 15:39:51

StringBuilder 是非线程安全的,检查是存在多线程调用

眼泪淡了忧伤 2021-12-09 15:39:48

换一个servlet容器试试?先确定问题。用apache工具IOUtils从request中读取数据试试?

无法言说的痛 2021-12-09 15:39:45

看看是不ppos 加大tomcat的size 应该就可以了

猫烠⑼条掵仅有一顆心 2021-12-09 15:39:45

收到的很小,60K多。tomcat我给了50M

多情癖 2021-12-09 15:39:41

我把读取客户端流数据的代码贴出来吧

空城仅有旧梦在 2021-12-09 15:39:41
public static String getBodyString(ServletRequest request) {
    StringBuilder sb = new StringBuilder();
    InputStream inputStream = null;
    BufferedReader reader = null;

    try {
        inputStream = request.getInputStream();
        reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
        String line = "";

        while((line = reader.readLine()) != null) {
            sb.append(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if(inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if(reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    return sb.toString();
}
各自安好 2021-12-09 15:39:40

1、你必须用POST请求。

2、你在使用 InputStream/OutputStream 时注意调用 flush() 保证缓冲区遗留的数据全部读完。

3、注意 close InputStream。

4、楼上提到的线程安全问题,你会不会误写了某个变量被多个线程共享读写了、导致偶尔并发了读得内容不完整。

千纸鹤带着心事 2021-12-09 15:39:19

怎么说呢?我是在controller里面直接读取字节流,如果有线程安全问题 那就是 servlet的问题了? 但是我不明白直接通过getInputStream 然后解析成字符串 这个过程怎么会存在线程安全问题呢。

醉生梦死 2021-12-09 15:33:27

回复
@coder4j : 之间我也遇到过类似的问题,最后定位就是线程不安全,在高并发的时候出现数据不全~

少女净妖师 2021-12-09 15:10:55

肯定是post,否则进不了controller

冷默言语 2021-12-09 14:04:57

看看你的 请求 是否是post的 方式提交的如果是get会出现长度限制的

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文