Spring WebClient调用POST接口触发Jackson JSON解析错误问题求助
问题排查结论
报错根本原因
- 服务端返回格式与客户端解析规则不匹配:你提供的服务端
save方法返回的是纯文本字符串(比如message success sended),但客户端WebClient配置了accept(MediaType.APPLICATION_JSON),且调用了bodyToMono(BulkSmsRequestResourceTest.class)试图将返回值反序列化为Java对象,Jackson会把服务端返回的纯文本内容当作JSON格式解析。 - 纯文本内容没有JSON要求的大括号、引号等标识,解析时第一个识别到的内容就是
message,不符合JSON语法规范,因此抛出对应解析异常。 - 数据能成功入库的原因是:异常发生在客户端接收服务端返回结果后的解析阶段,此时服务端已经完成了入库逻辑再返回响应,所以入库操作不受客户端解析异常的影响。
解决方案
方案1:统一前后端响应格式(推荐)
修改服务端接口,不要直接返回字符串,统一返回JSON结构的响应对象(和你项目中使用的SuccessResponseResource、ErrorResponseResource对齐),保证响应头Content-Type为application/json,客户端即可正常解析返回结果。
方案2:适配服务端现有返回格式
如果服务端逻辑暂时无法修改,将客户端WebClient的解析逻辑修改为接收纯文本即可,把代码中的:
.bodyToMono(BulkSmsRequestResourceTest.class);
修改为:
.bodyToMono(String.class);
额外代码优化建议
你当前的写法属于“发完就忘”的异步调用:直接调用subscribe()后立刻返回成功响应,无法感知远程调用的超时、异常等问题,前端会收到不符合实际状态的成功结果,建议调整为流式处理返回,参考代码:
@Override public Mono<ResponseEntity<? extends ResponseResource>> sendSms(BulkSmsRequestResourceTest request) { if (request == null) { return Mono.just(new ResponseEntity<>(new ErrorResponseResource("Transaction failed unsuccessfully!",400),HttpStatus.BAD_REQUEST)); } return webClientBuilder.build() .post() .uri(sendSmsService) .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON) .body(Mono.just(request), BulkSmsRequestResourceTest.class) .retrieve() // 根据服务端返回类型填写String或对应响应对象类 .bodyToMono(String.class) .map(res -> new ResponseEntity<>(new SuccessResponseResource("Transaction done successfully", 200), HttpStatus.OK)) .onErrorResume(e -> Mono.just(new ResponseEntity<>(new ErrorResponseResource("远程调用失败:" + e.getMessage(), 500), HttpStatus.INTERNAL_SERVER_ERROR))); }
内容的提问来源于stack exchange,提问作者iwritecomeinmymind
相关产品推荐
相关产品推荐

