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

GET接口带@RequestBody调用异常:服务B调用服务A报请求体缺失

问题根源

  1. HTTP规范与Spring注解冲突:服务A的接口用@GetMapping却搭配了@RequestBody,这违背了HTTP设计规范——GET请求语义是获取资源,通常不携带请求体。Postman能调用成功是因为它允许GET请求带请求体(非常规用法),但Spring的RestTemplate.getForObject()严格遵循规范,不会将HttpEntity中的请求体发送出去,导致服务A收到的请求无请求体,触发400错误。
  2. RestTemplate方法选型错误:getForObject()是专门用于GET请求的方法,仅支持通过URL路径变量或查询参数传递参数,不支持携带请求体,你构造的HttpEntity在这里完全无效。

两种解决办法

办法一:改用POST请求(推荐)

接口需要传递复杂参数时,POST请求更符合HTTP语义:

  • 修改服务A的接口:
@PostMapping(value = "/reservationsCheck")
public List<LockerReservations> getReservationsCheck(@RequestBody Map<String, Object> requestMap) {
    return bookingService.availabilityCheckSizeTime(
            Size.valueOf((String) requestMap.get("size")),
            LocalDateTime.parse((CharSequence) requestMap.get("start")),
            LocalDateTime.parse((CharSequence) requestMap.get("end")));
}
  • 修改服务B的调用代码:
    将getForObject()替换为postForObject():
String url = "http://localhost:8080/v1/api/";

public List<LockerReservations> getReservationsCheck(Size size, LocalDateTime start, LocalDateTime end) {
    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.setContentType(MediaType.APPLICATION_JSON);
    Map<String, Object> sizeTimeMap = new HashMap<>();
    sizeTimeMap.put("size", size);
    sizeTimeMap.put("start", start);
    sizeTimeMap.put("end", end);
    HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<>(sizeTimeMap, httpHeaders);
    LockerReservations[] result = restTemplate.postForObject(url + "reservationsCheck", httpEntity, LockerReservations[].class);
    return List.of(result);
}

办法二:坚持用GET请求,改用查询参数传递

如果必须使用GET,将参数放到URL查询参数中:

  • 修改服务A的接口:
    去掉@RequestBody,改用@RequestParam接收参数:
@GetMapping(value = "/reservationsCheck")
public List<LockerReservations> getReservationsCheck(
        @RequestParam("size") String size,
        @RequestParam("start") String start,
        @RequestParam("end") String end) {
    return bookingService.availabilityCheckSizeTime(
            Size.valueOf(size),
            LocalDateTime.parse(start),
            LocalDateTime.parse(end));
}
  • 修改服务B的调用代码:
    通过getForObject()传递查询参数:
String url = "http://localhost:8080/v1/api/reservationsCheck?size={size}&start={start}&end={end}";

public List<LockerReservations> getReservationsCheck(Size size, LocalDateTime start, LocalDateTime end) {
    String startStr = start.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
    String endStr = end.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
    LockerReservations[] result = restTemplate.getForObject(url, LockerReservations[].class, 
            size.name(), startStr, endStr);
    return List.of(result);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 03:35:39