【问题】【SpringBoot】记一次springboot框架下用jackson解析RequestBody失败的问题
最近项目中遇到了一个问题,费好大劲才发现问题所在,并且修复了问题,下面分享一下这个问题的定位和修复的新路旅程。
先说下背景:该项目用的是SpringBoot框架,主要功能为对外提供一些Restful API,使用的Servlet容器是默认的Tomcat,Json解析工具是默认的Jackson,通过@RequestBody注解来解析body。
再说下问题:用户通过https方法调用POST方法的接口,会偶现Jackson解析Json体失败的问题。这个问题比较离奇,同样的数据,同样的接口,有时候会发生解析失败。大概成功10+次会失败一次的频率。报错信息如下:
JSON parse error: Unexpected end-of-input: expected close marker for Object (start marker at [Source: (PushbackInputStream); line: 1, column: 1]);
nested exception is com.fasterxml.jackson.core.io.JsonEOFException: Unexpected end-of-input: expected close marker for Object (start marker at
[Source: (PushbackInputStream); line: 1, column: 1])\n at [Source: (PushbackInputStream); line: 1, column: 3]。
值得一提的是,line和column的值每次都会不一样。
由于服务部署在公有云上,依赖的周边服务有不少,所以要先进行问题的定界。
- 不通过公有云注册的API,而是直接通过公网IP:PORT的形式调用,问题复现。排除APIG服务问题。
- 进入容器节点,直接调用容器内的pod ip,问题复现。排除k8s或者CCE服务的问题。
- 至此,已经能排除公有云服务的问题,可以专注定位是否是框架或者实现有问题。
接下来观察一下报错信息,显然是解析body体出了问题,看起来像是body体不完整导致的,而且每次提示的line和column值都不一样,感觉是body体在哪里被截断了。那很自然的会做以下猜测:
- body体本身不合法。不再赘述,推荐一个在线平台 bejson。
- https请求对body内容做了拦截。查看请求头中是否包含Content-Length,如果包含的话,可能就是这个值有问题,把这个Content-Length从请求头中删除掉
- body体被spring框架拦截。
- body体被spring内的tomcat拦截。
--server.max-http-header-size=8192000
--server.tomcat.max-http-post-size=-1
--spring.server.tomcat.max-http-header-size=52428800
--spring.server.tomcat.max-http-post-size=-1
--spring.http.multipart.max-file-size=1000m
--spring.http.multipart.max-request-size=1000m
spring和tomcat的配置有很多,找了很多参数,都没有解决问题,行吧,只能打断点看了。
经过测试本地无法复现,那就只能对远程服务器上的deployment进行远程debug。基于IDEA进行springboot工程的远程调试方法见我之前的blog:基于IDEA对springboot做远程调试
根据日志打出来的栈信息,不难找到是在AbstractJackson2HttpMessageConverter. readJavaType方法报的错,这个Converter方法其实就是spring-web的http消息转换器,
readJavaType方法定义:
private Object readJavaType(JavaType javaType, HttpInputMessage inputMessage) throws IOException
报错信息显示在这一行:
return this.objectMapper.readValue(inputMessage.getBody(), javaType)
这里调用了Jackson的readValue方法对message这个流进行解析,那我们从这里开始单步调试,下一步应该进到jackson的readValue方法了,此时通过ctrl+左键进入这个方法,
发现jackson-core的版本为2.11.2,而报错的栈信息中jackson-core版本为2.10.2,两边的版本不一致?
由于spring-web版本是spring starter中指定的,带着疑问,我尝试着把starter的版本升级到最新的2.3.0.RELEASE,对环境上的应用进行了升级,
问题不再复现…好吧,终于解决。之前用的starter是2.2.5.RELEASE,有可能是仓库中的该版本包有问题,亦或是这个版本下spring-web的版本就是有BUG,这个不得而知了…
【问题】【SpringBoot】记一次springboot框架下用jackson解析RequestBody失败的问题的更多相关文章
- SpringBoot项目框架下ThreadPoolExecutor线程池+Queue缓冲队列实现高并发中进行下单业务
主要是自己在项目中(中小型项目) 有支付下单业务(只是办理VIP,没有涉及到商品库存),目前用户量还没有上来,目前没有出现问题,但是想到如果用户量变大,下单并发量变大,可能会出现一系列的问题,趁着空闲 ...
- 基于Maven的Springboot+Mybatis+Druid+Swagger2+mybatis-generator框架环境搭建
基于Maven的Springboot+Mybatis+Druid+Swagger2+mybatis-generator框架环境搭建 前言 最近做回后台开发,重新抓起以前学过的SSM(Spring+Sp ...
- 【spring-boot】快速构建spring-boot微框架
spring-boot是一个快速构建环境的一套框架,其设计理念是尽可能的减少xml的配置,用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义 ...
- 记一次SpringBoot 开发中所遇到的坑和解决方法
记一次SpringBoot 开发中所遇到的坑和解决方法 mybatis返回Integer为0,自动转型出现空指针异常 当我们使用Integer去接受数据库中表的数据,如果返回的数据中为0,那么Inte ...
- JAVAEE——SpringBoot日志篇:日志框架SLF4j、日志配置、日志使用、切换日志框架
Spring Boot 日志篇 1.日志框架(故事引入) 小张:开发一个大型系统: 1.System.out.println(""):将关键数据打印在控制台:去掉?写在一个文件 ...
- 基于Netty和SpringBoot实现一个轻量级RPC框架-协议篇
基于Netty和SpringBoot实现一个轻量级RPC框架-协议篇 前提 最近对网络编程方面比较有兴趣,在微服务实践上也用到了相对主流的RPC框架如Spring Cloud Gateway底层也切换 ...
- 基于Netty和SpringBoot实现一个轻量级RPC框架-Server篇
前提 前置文章: Github Page:<基于Netty和SpringBoot实现一个轻量级RPC框架-协议篇> Coding Page:<基于Netty和SpringBoot实现 ...
- 基于Netty和SpringBoot实现一个轻量级RPC框架-Client篇
前提 前置文章: <基于Netty和SpringBoot实现一个轻量级RPC框架-协议篇> <基于Netty和SpringBoot实现一个轻量级RPC框架-Server篇> 前 ...
- 记一次springboot项目,maven引发的悲剧(Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletCont)
maven下载大的项目的时候,jar包下载出错是常见的, 但是这种情况经常能看到,如java.lang.ClassNotFoundException这样的提示, 所以一直以来也觉得maven下载jar ...
随机推荐
- excel-填充
问题[1]:需要将一列元素的空全部填充为NULL 选定列->F5定位(推荐先定位行总数)->再次F5定位(选空值)->在选定后的一个框内输入NULL->ctrl+enter 完 ...
- Fault-Tolerance, Fast and Slow: Exploiting Failure Asynchrony in Distributed Systems
本文(OSDI 18')主要介绍一种新的副本复制协议:SAUCR(场景可感知的更新与故障恢复).它是一种混合的协议: 在一定场景(正常情况)下:副本复制的数据缓存在内存中. 故障发生时(多个节点挂掉, ...
- Python10行以内代码能有什么高端操作
Python10行以内代码能有什么高端操作 Python凭借其简洁的代码,赢得了许多开发者的喜爱.因此也就促使了更多开发者用Python开发新的模块,从而形成良性循环,Python可以凭借更加简短的代 ...
- Navicat Premium 安装破解
软件官网 : https://www.navicat.com.cn/ Navicat Premium 12 下载地址:https://www.lanzous.com/i9j0syf 密码:7pup N ...
- java_线程、同步、线程池
线程 Java使用 java.lang.Thread 类代表线程,所有的线程对象都必须是Thread类或其子类的实例 Thread类常用方法 构造方法 public Thread():分配一个新的线程 ...
- Elasticsearch第三篇:查询详解
从第一篇开始,我用的ES版本就是7.8.0的,与低版本略有不同,不同点可以参考官方介绍,最大的不同就是抛弃 type 这一概念,为了方便测试,首先建立一个学生成绩的索引库(在建立的同时,规定字段类型, ...
- java循环语句for与无限循环
一 for循环 for循环语句是最常用的循环语句,一般用在循环次数已知的情况下. 格式: for(初始化表达式; 循环条件; 操作表达式){ 执行语句 ……… } 循环流程: for(① ; ② ; ...
- vue 公众号H5 使用微信JSAPI 录音 完整齐全
官方文档必须首当其冲 1.微信jsAPI 录音文档 2.获取微信临时素材文档 首先H5录音功能的话 对于普通H5网上是有很多的方法 插件 但是兼容性很差 特别是对于ios 一开始想的是用H5 做个通 ...
- Python中ansible的使用
#!/usr/bin/env python # -*- coding: utf8 -*- # @Author: huangmanyao from ansible import constants fr ...
- 调试备忘录-RS485 MODBUS RTU协议简述
目录--点击可快速直达 目录 写在前面 先简单说下什么是MODBUS? 参考文章 写在前面 最近在做和物联网有关的小项目,有一个传感器通讯用到了RS485 MODBUS RTU协议,所以就写个随笔记录 ...