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

@DeleteMapping端点未触发排查:WebClient调用无响应无报错

WebClient调用@DeleteMapping接口未触发的问题排查

问题描述

使用WebClient调用@GetMapping接口正常,但@DeleteMapping接口完全未触发。执行删除操作时无任何错误状态码(如405、400、403),WebClient调用返回MonoIgnorePublisher对象,但后端@DeleteMapping方法内的断点未触发。

调用代码

// 正常工作的Get请求
MyItem myItem = webClient.get()
    .uri(url + "/items/" + tenant + "/" + itemId)
    .accept(MediaType.APPLICATION_JSON)
    .retrieve()
    .bodyToMono(MyItem.class)
    .block();

// 未触发Delete端点的请求
Mono<Void> resp = webClient.delete()
    .uri(url + "/items/" + tenant + "/" + itemId)
    .retrieve()
    .bodyToMono(Void.class)
    .then();

后端端点定义

@RestController
@RequestMapping("/items/{tenant}")
public class ItemController {
    @GetMapping("/{id}")
    public MyItem findById(@PathVariable String id, @PathVariable String tenant, Authentication auth) {
        // 业务逻辑
    }

    @DeleteMapping("/{id}")
    public void deleteById(@PathVariable String id, @PathVariable String tenant, Authentication auth) {
        // 断点设置在此处,但未触发
        // 业务逻辑
    }
}

可能的原因及解决方法

  • 反应式流未被订阅执行:WebClient的delete请求返回Mono,但代码仅赋值给变量未触发订阅。反应式流只有在调用block()、subscribe()等订阅方法时才会实际发送请求。对比Get请求用了block()触发执行,Delete请求需补充订阅逻辑:

    // 同步等待执行
    webClient.delete()
        .uri(url + "/items/" + tenant + "/" + itemId)
        .retrieve()
        .bodyToMono(Void.class)
        .block();
    
    // 异步执行
    webClient.delete()
        .uri(url + "/items/" + tenant + "/" + itemId)
        .retrieve()
        .bodyToMono(Void.class)
        .subscribe();
    
  • URI拼接错误:手动拼接URL容易出现路径重复或格式错误。后端@RequestMapping是/items/{tenant}/{id},若url本身已包含/items,拼接后会变成/items/items/{tenant}/{id},导致路径不匹配。建议使用URI占位符方式避免错误:

    webClient.delete()
        .uri("{baseUrl}/items/{tenant}/{id}", url, tenant, itemId)
        .retrieve()
        .bodyToMono(Void.class)
        .block();
    
  • 后端Void返回值的处理问题:后端delete方法返回void,WebClient用bodyToMono(Void.class)可能无法正确识别响应。可以改用无实体响应的处理方式,同时验证响应状态:

    webClient.delete()
        .uri(...)
        .retrieve()
        .toBodilessEntity() // 处理无实体响应
        .block();
    
  • 请求被拦截器/过滤器拦截:检查项目中的拦截器、Spring Security配置等,是否仅允许Get请求通过,而拦截了Delete请求。比如Security配置中是否未对/items/**的Delete请求放开权限。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 16:57:16