Spring WebFlux 控制层异常处理出现Jackson序列化错误问题咨询
问题原因
你遇到的错误由三个核心问题共同导致:
- 代码笔误:
onErrorResume回调中将ResponseEntity误写为拆分的Response entity,大概率同时错误导入了WebFlux函数式编程的ServerResponse相关类而非Spring Web的ResponseEntity,导致返回的是WebFlux内部的DefaultEntityResponse对象,Spring会将该对象当作普通Bean序列化,而该类没有公开可序列化的getter字段,触发Jackson序列化异常。 - 类型不匹配:
onErrorResume要求返回Publisher类型(即Mono/Flux),你直接返回响应对象而非用Mono.just()包裹,导致返回值类型与Controller方法声明的Mono<ResponseEntity<Object>>不匹配。 - 异常序列化问题:直接将
IllegalArgumentException异常对象塞入响应体,Java原生异常没有适合Jackson序列化的公开字段结构,容易触发序列化失败。
序列化过程抛出的新异常会被Spring的默认兜底逻辑处理,最终返回200状态码,不符合预期。
修复方案
- 修正代码笔误和类型问题,确保导入
org.springframework.http.ResponseEntity,所有flatMap、onErrorResume回调都返回Mono包装的ResponseEntity对象 - 用简单结构封装错误信息,避免直接序列化异常对象
修正后的Controller代码示例:
@RestController @RequiredArgsConstructor @RequestMapping("/user") public class AppUserController { private final AppUserService appUserService; private final PasswordEncoder encoder; @GetMapping public Flux<AppUser> getAllUsers(@RequestHeader("email") String email) { return appUserService.getAllUsers(); } @PostMapping @CrossOrigin public Mono<ResponseEntity<Object>> saveUser(@RequestBody Mono<AppUser> appUserMono) { return appUserMono .doOnSuccess(appUser -> appUser.setPassword(encoder.encode(appUser.getPassword()))) .subscribeOn(Schedulers.parallel()) .flatMap(appUserService::saveUser) .flatMap(savedAppUser -> Mono.just(ResponseEntity.created(URI.create("/user/" + savedAppUser.getId())).build())) .onErrorResume(error -> Mono.just( ResponseEntity.badRequest().body(Map.of("errorMessage", error.getMessage())) )) .log(); } }
可选优化
可以使用@ControllerAdvice全局处理WebFlux异常,无需每个接口单独编写onErrorResume逻辑,统一异常返回格式。
内容的提问来源于stack exchange,提问作者Devbrat Dash
相关产品推荐
相关产品推荐

