如何将Mono<String>类型的JSON解析转换为Mono<Object>?
解决方案
要在不使用block()的前提下将Mono<String>转换为Mono<Object>,核心是利用响应式流的map操作符,在异步流中完成JSON清理和对象转换,全程保持响应式特性。
步骤1:定义对应JSON结构的实体类
根据返回的JSON结构,创建匹配的Java实体类(如果需要强类型对象):
public class ApiResponse { private Result result; // Getter、Setter } public class Result { private Books books; private Response response; // Getter、Setter } public class Books { private Book book; // Getter、Setter } public class Book { private String creator; private String created; private String author; // Getter、Setter } public class Response { private String respMsg; private String respCode; // Getter、Setter }
步骤2:通过map操作符完成转换
使用Mono的map方法,依次执行JSON清理和对象解析操作:
// 注入Spring提供的ObjectMapper(或自行实例化) @Autowired private ObjectMapper objectMapper; // 原Mono<String>响应 Mono<String> rawResponse = webClient.post() .uri(new URI(url)) .body(BodyInserters.fromMultipartData(multiValueMap)) .retrieve() .bodyToMono(String.class); // 转换为Mono<ApiResponse> Mono<ApiResponse> targetMono = rawResponse // 先执行JSON清理 .map(JsonSanitizer::sanitize) // 将清理后的JSON字符串解析为目标对象 .map(sanitizedJson -> { try { return objectMapper.readValue(sanitizedJson, ApiResponse.class); } catch (JsonProcessingException e) { throw new RuntimeException("JSON解析失败", e); } });
若不需要强类型对象(转为Map)
如果不需要实体类,也可以直接转换为Mono<Map<String, Object>>:
Mono<Map<String, Object>> mapMono = rawResponse .map(JsonSanitizer::sanitize) .map(sanitizedJson -> { try { return objectMapper.readValue(sanitizedJson, new TypeReference<Map<String, Object>>() {}); } catch (JsonProcessingException e) { throw new RuntimeException("JSON解析失败", e); } });
关键说明
map操作符是响应式的,会在数据流异步流转时执行,不会阻塞线程,完全符合Reactor的响应式设计原则,避免了block()带来的线程阻塞和响应式流破坏问题。- 如果不需要先执行
JsonSanitizer.sanitize,可以直接让WebClient返回目标对象的Mono:
Mono<ApiResponse> directResponse = webClient.post() .uri(new URI(url)) .body(BodyInserters.fromMultipartData(multiValueMap)) .retrieve() .bodyToMono(ApiResponse.class);
内容的提问来源于stack exchange,提问作者user21476047
相关产品推荐
相关产品推荐

