[스프링부트] FeignClient @FormProperty와 자바 record 클래스
구글 OAuth2를 위해 Feign Client 사용하던 중 발생했던 문제
액세스 토큰을 얻으려면 5단계: 승인 코드를 갱신 토큰 및 액세스 토큰으로 교환 에 나온대로
Content-Type: application/x-www-form-urlencoded 그리고 필드는 다음과 같이 작성해서 보내야한다.
| client_id | 클라이언트 ID |
| client_secret | 클라이언트 secret key |
| code | 초기 요청에서 반환된 승인 코드입니다. |
| grant_type | OAuth 2.0 사양에 정의된 대로 이 필드의 값은 authorization_code로 설정해야 합니다. |
| redirect_uri | 지정된 client_id의 에 프로젝트에 대해 나열된 리디렉션 URI 중 하나입니다. |
그래서 필드는 확정적이니까 request dto를 평소처럼 record로 작성했다.
액세스 토큰을 얻기 위한 Feign Client 인터페이스는와 dto는 다음과 같다.
@FeignClient(name = "googleAuthClient", url = "https://oauth2.googleapis.com", configuration = OAuth2FeignConfig.class)
public interface GoogleOAuthClient {
@PostMapping(value = "/token", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
GoogleOAuthResponse getToken(@RequestBody GoogleOAuthRequest request);
}
@Builder
public record GoogleOAuthRequest(
String code,
@FormProperty("client_id")
String clientId,
@FormProperty("client_secret")
String clientSecret,
@FormProperty("redirect_uri")
String redirectUri,
@FormProperty("grant_type")
String grantType
) {
}
이렇게 작성하고 API를 찔러보니 4xx에러가 날라왔다. 원인을 찾다가 body에 들어가는 내용을 확인했더니, @FormProperty에 적힌대로 수정되어 request body에 들어가는게 아닌, 필드명 그대로 들어가는 것을 확인했다. (예를 들면, client_id가 아닌 clientId로 들어간다.)
왜지..? 그래서 FormProperty 오류를 찾아보다 해당 글을 발견했다. FeignClient @FormProperty 트러블 슈팅
링크를 건 포스트를 요약하면, @FormProperty로 설정된 이름으로 매핑되려면 해당 필드는 final 혹은 static이면 안된다는 것이다. 그런데 record를 사용하면 각 필드는 private final로 바뀌게 됨으로써 @FormProperty가 무시되는 것.
그래서 안타깝지만 dto를 일반 class로 변경했다.
@Builder
public class GoogleOAuthRequest {
private String code;
@FormProperty("client_id")
private String clientId;
@FormProperty("client_secret")
private String clientSecret;
@FormProperty("redirect_uri")
private String redirectUri;
@FormProperty("grant_type")
private String grantType;
}
이후 요청을 보냈더니, 정상적인 응답을 받을 수 있었다.
'개발 > 에러' 카테고리의 다른 글
| [Spring Boot/JPA] globally_quoted_identifiers와 네이밍 전략 이슈 (0) | 2026.02.16 |
|---|---|
| 윈도우 사용중인 포트 / TCP 포트 제외 범위로 인한 어플리케이션 실행 불가 (0) | 2025.05.11 |