起因
有一个需求是请求A系统开放接口HTTP方式获取token值,用于后续操作。刚开始话先使用postman进行参数组装进行调试获取到token后发现可以正常使用 然后进行Java编码开发。使用restTemplate进行HTTP调用。
问题
后来发现获取的结果参数与postman请求的结果格式是一样的,但是token是不可用的。刚开始想的是一样的请求参数按理说得到的机构是一样的,就把请求参数给打印出来发到postman试了一下,结果发现同样的请求参数postman可以使用,restTemplate就是不能使用。 中间还尝试用过okhttp原生调用方式去请求,发现也是可以使用的。
感觉问题就在restTemplate。但经过了一些配置参数的调整并没有什么作用(这一步耗费了很长时间)。就想看一下restTemplate真正发出后的HTTP请求是什么样子。与okhttp调用的请求参数做一个对比。就写了一个接受HTTP请求的接口看一看请求到底是什么样子
调试后发现两者请求在于 dashboard字段为null时,restTemplate会把dashboard字段传null,okhttp会不上传dashboard字段。到此终于发现变量在这里。
解决方案
修改restTemplate的序列化方式,当字段为null时不上传该字段,到此问题解决。
// 创建 ObjectMapper 对象并设置 WRITE_NULL_MAP_VALUES 特性 当字段为null时不进行序列化
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(objectMapper);
反思
- 发现问题时,先找变量没有错,但要挖掘最核心的变量,这个问题如果直接从服务端去接收多个请求的参数再去比较就很容易发现问题。
- 后端设计接口时应该考虑:字段为null和不上传字段时,这两种情况本质上是一样的。后端应该兼容这个场景