Webflux集成测试出现UnsupportedOperationException问题求助
问题原因与解决方案
核心原因
问题出在**ResponseEntity.ok()构建的响应头会被Spring自动设置为只读状态**,后续EncoderHttpMessageWriter尝试修改Content-Length时触发异常:
- 当你返回
ResponseEntity.ok(userMapper.map(userList))时,Spring会自动计算响应体长度并设置Content-Length,此时HttpHeaders被包装成ReadOnlyHttpHeaders(不可修改)。 - 集成测试环境下,
EncoderHttpMessageWriter的逻辑会再次调用setContentLength()尝试覆盖该值,而只读头不允许修改,直接抛出UnsupportedOperationException。
解决方案
方案1:直接返回响应体(推荐)
放弃手动构建ResponseEntity,让Webflux框架自动处理响应头,避免只读头问题:
@GetMapping public Mono<List<UserWebModel>> getUsers() { Flux<User> users = loadUserService.getusers(getUserIdFromToken()); return users.collectList() .map(userMapper::map) .switchIfEmpty(Mono.error(new ResponseStatusException(HttpStatus.NOT_FOUND))); }
方案2:手动构建可修改的HttpHeaders
如果必须使用ResponseEntity,需要手动创建可修改的HttpHeaders对象,再构建响应:
@GetMapping public Mono<ResponseEntity<List<UserWebModel>>> getUsers() { Flux<User> users = loadUserService.getusers(getUserIdFromToken()); return users.collectList() .map(userList -> { HttpHeaders headers = new HttpHeaders(); // 自定义头可在此设置,框架后续会自动处理Content-Length return new ResponseEntity<>(userMapper.map(userList), headers, HttpStatus.OK); }) .switchIfEmpty(Mono.just(ResponseEntity.status(HttpStatus.NOT_FOUND).build())); }
方案3:检查测试中的JWT配置
确认mockJwt()的配置是否正确,部分情况下JWT过滤器可能提前修改响应头导致其变为只读,不过优先尝试前两种方案。
内容的提问来源于stack exchange,提问作者dorty
相关产品推荐
相关产品推荐

