Search code examples
javaspring-cloud-feign

Feign throws 404 Not Found but the link does work


I have some questions about using Feign in Spring Cloud. I have a FeignClient:

@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 Request dto);
}

record Request(
    @RequestParam(name = "client_id") String clientId,
    @RequestParam(name = "scope") String scope
) implements Serializable { }

But when I call function DeviceCodeCheckClient#getTokenByDeviceCode, it throw feign.FeignException$NotFound:

10:29:28.267 ERROR (DirectJDKLog.java:175): Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is feign.FeignException$NotFound: [404 Not Found] during [POST] to [https://login.microsoftonline.com/common/oauth2/v2.0/devicecode] [AzureTokenClient#getDeviceCode(Request)]: []] with root cause
feign.FeignException$NotFound: [404 Not Found] during [POST] to [https://login.microsoftonline.com/common/oauth2/v2.0/devicecode] [AzureTokenClient#getDeviceCode(Request)]: []
    at feign.FeignException.clientErrorStatus(FeignException.java:219)
    at feign.FeignException.errorStatus(FeignException.java:194)
    at feign.FeignException.errorStatus(FeignException.java:185)
...

Obviously, the link https://login.microsoftonline.com/common/oauth2/v2.0/devicecode is correct and accessible. I would like to know why Feign is giving error 404 and how can I fix this? Thank you!


Solution

  • The annotation @RequestBody will serialize the object to json or xml, but consumes specifies the format as application/x-www-form-urlencoded, which causes the body in the request sent by Feign to be empty, so the microsoft server returns a 404 Not Found response.

    To solve this problem, the @RequestBody annotation should be removed:

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