Spring WebClient用retrieve调用接口遇UnsupportedMediaTypeException如何解决
问题根因
你遇到的异常本质是404状态码返回的响应Content-Type为text/plain,和后续反序列化指定的DTODemo类型需要的媒体类型不匹配,导致反序列化失败。
解决方案
完全可以仅用retrieve()方法实现需求,核心是使用retrieve()内置的onStatus状态码拦截器,在进入反序列化逻辑前先处理404场景的响应,示例代码如下:
方案1:404时抛出携带错误信息的异常
ResponseEntity<DTODemo> responseEntity = webClient.get() .uri("http://localhost:8051/callAPI/") .retrieve() // 拦截404状态码的响应 .onStatus(status -> status == HttpStatus.NOT_FOUND, clientResponse -> // 读取404返回的纯文本错误提示 clientResponse.bodyToMono(String.class) .flatMap(errorMsg -> Mono.error(new RuntimeException("接口404错误:" + errorMsg))) ) .toEntity(DTODemo.class) .block();
方案2:404时返回自定义默认结构,不抛出异常
如果业务需要404时也返回封装好的DTODemo对象,可以搭配onErrorResume实现:
// 先自定义404异常类,也可以直接用RuntimeException class Custom404Exception extends RuntimeException { public Custom404Exception(String message) { super(message); } } // 调用逻辑 ResponseEntity<DTODemo> responseEntity = webClient.get() .uri("http://localhost:8051/callAPI/") .retrieve() .onStatus(status -> status == HttpStatus.NOT_FOUND, clientResponse -> clientResponse.bodyToMono(String.class) .flatMap(errorMsg -> Mono.error(new Custom404Exception(errorMsg))) ) .toEntity(DTODemo.class) // 捕获自定义404异常,构造符合要求的返回值 .onErrorResume(Custom404Exception.class, e -> { DTODemo dto = new DTODemo(); // 可将错误信息写入dto的对应字段,也可以直接返回null dto.setErrorMsg(e.getMessage()); return Mono.just(new ResponseEntity<>(dto, HttpStatus.NOT_FOUND)); }) .block();
说明
- 以上方案完全使用
retrieve原生能力,不需要调用exchange相关方法 - 你可以根据业务需要调整
onStatus的状态码匹配规则,比如同时处理所有4xx类错误,只需要修改status判断逻辑即可 - 如果有多个状态码对应不同的响应类型,可定义多个
onStatus处理器分别处理
内容的提问来源于stack exchange,提问作者Samshay
相关产品推荐
相关产品推荐

