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

Feign调用返回404 Not Found但链接可正常访问的问题排查

Feign调用Azure设备码接口返回404的原因及解决方法

问题原因

你的代码存在两个核心问题,导致请求不符合Azure设备码接口的要求:

  1. 请求体格式不匹配:方法上使用@RequestBody注解后,Feign会将Request对象序列化为JSON格式发送,但接口要求的是application/x-www-form-urlencoded的表单格式,Azure服务器无法正确解析该请求,进而返回404错误。
  2. 参数注解无效:Request record字段上的@RequestParam注解不会被Feign识别——该注解仅作用于方法参数层面,因此实际请求中并未携带client_id和scope参数,接口因缺少必要参数判定请求无效。

解决方法

以下三种方案均可解决问题,任选其一即可:

方案一:直接使用@RequestParam作为方法参数

将参数直接定义在方法上,Feign会自动将其拼接为表单格式:

@FeignClient(name = "device-code", url = AzureTokenClient.BASE_URL)
public interface AzureTokenClient {
    String SCOPE = URLEncoder.encode("offline_access files.read.all", Charsets.UTF_8);
    String BASE_URL = "https://login.microsoftonline.com";

    @PostMapping(value = "/common/oauth2/v2.0/devicecode", consumes = "application/x-www-form-urlencoded")
    Map<String, Object> getDeviceCode(@RequestParam("client_id") String clientId, @RequestParam("scope") String scope);
}

方案二:使用@ModelAttribute封装参数

保留Request record,去掉字段上的@RequestParam,方法参数使用@ModelAttribute注解,Feign会自动将record字段转为表单参数:

@FeignClient(name = "device-code", url = AzureTokenClient.BASE_URL)
public interface AzureTokenClient {
    String SCOPE = URLEncoder.encode("offline_access files.read.all", Charsets.UTF_8);
    String BASE_URL = "https://login.microsoftonline.com";

    @PostMapping(value = "/common/oauth2/v2.0/devicecode", consumes = "application/x-www-form-urlencoded")
    Map<String, Object> getDeviceCode(@ModelAttribute Request dto);
}

record Request(String clientId, String scope) implements Serializable { }

方案三:使用MultiValueMap作为请求体

直接构建表单格式的请求体,适合参数较多或动态参数的场景:

@FeignClient(name = "device-code", url = AzureTokenClient.BASE_URL)
public interface AzureTokenClient {
    String SCOPE = URLEncoder.encode("offline_access files.read.all", Charsets.UTF_8);
    String BASE_URL = "https://login.microsoftonline.com";

    @PostMapping(value = "/common/oauth2/v2.0/devicecode", consumes = "application/x-www-form-urlencoded")
    Map<String, Object> getDeviceCode(@RequestBody MultiValueMap<String, String> params);
}

调用时构建参数:

MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("client_id", "你的客户端ID");
params.add("scope", AzureTokenClient.SCOPE);
azureTokenClient.getDeviceCode(params);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 11:06:48