ApiService에서 webclient를 이용하여 외부 API 호출 로직.
웹페이지 내에서 인증키를 입력하여 테스트했을 때는 통과했던 것이 Spring 이용하여 호출하니 SERVICE_KEY_IS_NOT_REGISTERED_ERROR: 등록되지 않은 서비스키 에러 발생
webclient는 baseUrl을 담아 Bean으로 등록한 상태
ApiService는
@Service
public class ApiService {
@Autowired
private WebClient webClient;
@Value("${api.key.encoding}")
private String APIEncodingKey;
public Response getData(){
Response response = webClient.get()
.uri(uriBuilder -> uriBuilder
.path(String.format("/B551177/PassengerNoticeKR/getfPassengerNoticeIKR"))
.queryParam("serviceKey", APIEncodingKey)
.queryParam("selectdate","0")
.queryParam("type","json").build())
.retrieve().bodyToMono(Response.class).block();
return response;
}
위와 같이 나타난다.
위의 시크릿키와 내가 넣은 시크릿키를 비교했더니 둘이 다르다..!!
이미 @Value를 통해 넘긴 값이 이미 인코딩된 키이지만 uri()에서 한 번 더 인코딩했기 때문에 발생한 에러였다.
그러면 디코딩한 값을 넣으면 되겠다고 생각해서 넣었더니
이번에는 serviceKey 디코딩-> 인코딩해주지 않았다,,
'+'예약어가 인코딩되지 않고 호출됨
파라미터 인코딩 방법!
DefaultUriBuilderFactory Class의 인스턴스를 생성해준다.
해당 인스턴스를 활용하여 인코딩 Mode를 설정한다.
따라서 Bean 등록할 때 uribuild, 인코딩 모드를 설정한다.
@Configuration
public class WebClientConfig {
private final static String BASE_URL = "http://apis.data.go.kr";
@Bean
public WebClient webClient(){
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(BASE_URL);
factory.setEncodingMode(EncodingMode.VALUES_ONLY);
return WebClient.builder()
.uriBuilderFactory(factory)
.baseUrl(BASE_URL)
.build();
}
}