You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从RestTemplate迁移至WebFlux:如何将响应映射为Java DTO?

从RestTemplate迁移到WebClient:XML响应转Java DTO

原RestTemplate实现

RestTemplate restTemplate = new RestTemplate();
String url = "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml";
ResponseEntity<Envelope> response = restTemplate.getForEntity(url, Envelope.class);

你的WebClient尝试代码

Boolean webClient = WebClient.builder()
                .build()
                .get()
                .uri("https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml")
                .accept(MediaType.APPLICATION_XML)
                .exchangeToMono(res -> Mono.just(res.statusCode().equals(HttpStatus.OK)))
                .timeout(Duration.ofSeconds(2))
                .block();

正确的WebClient实现(转换为Envelope DTO)

// 建议全局单例复用WebClient,避免重复创建
WebClient webClient = WebClient.builder()
        .baseUrl("https://www.ecb.europa.eu")
        .build();

// 同步获取DTO(适配原有同步逻辑)
Envelope envelope = webClient.get()
        .uri("/stats/eurofxref/eurofxref-daily.xml")
        .accept(MediaType.APPLICATION_XML)
        .retrieve()
        // 自定义错误状态处理
        .onStatus(HttpStatus::isError, response -> 
            Mono.error(new RuntimeException("请求失败,状态码:" + response.statusCode()))
        )
        // 将XML响应体直接转换为目标DTO
        .bodyToMono(Envelope.class)
        .timeout(Duration.ofSeconds(2))
        .block();

// 异步场景推荐写法(无需block,返回Mono让调用方订阅)
// Mono<Envelope> envelopeMono = webClient.get()
//         .uri("/stats/eurofxref/eurofxref-daily.xml")
//         .accept(MediaType.APPLICATION_XML)
//         .retrieve()
//         .onStatus(HttpStatus::isError, response -> 
//             Mono.error(new RuntimeException("请求失败,状态码:" + response.statusCode()))
//         )
//         .bodyToMono(Envelope.class)
//         .timeout(Duration.ofSeconds(2));

核心要点说明

  • bodyToMono(Envelope.class):这是实现XML转DTO的关键,对应RestTemplate的类型转换逻辑。WebClient会通过内置的Jaxb2XmlDecoder解析XML,需确保你的Envelope类有正确的JAXB注解(比如@XmlRootElement、@XmlElement等)。
  • retrieve()简化处理:相比exchangeToMono(),retrieve()是更简洁的响应处理方式,自动识别2xx状态码,非2xx状态可通过onStatus()自定义错误逻辑。
  • WebClient实例复用:不要每次请求都创建WebClient实例,建议在Spring环境下通过@Bean配置全局单例,提升性能。
  • 同步vs异步:block()仅用于适配原有同步代码,WebFlux的最佳实践是保持异步流程,返回Mono<Envelope>让调用方通过订阅处理结果。

内容的提问来源于stack exchange,提问作者Peter Penzov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 03:38:18