ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 20230202 TIL RestTemplate으로 아임포트 API 호출하기
    TIL 2023. 2. 2. 17:45

    https://1.bp.blogspot.com/-MlGWLe08yvk/XZQ0w-7dIGI/AAAAAAAAroM/_wqQtsLyiOEpfp7kMZFVXZ6wl-oWKJfGwCLcBGAsYHQ/s1600/rt.PNG

    아임포트 API호출 시 access token이 필요한 경우가 있다.

    따라서 access token을 먼저 받아올 수 있는 issueAccessToken이라는 메서드를 만들었다.

    (api key와 api secret은 https://classic-admin.iamport.kr/settings에서 확인할 수 있다.)

     

    private static final String HOST = "https://api.iamport.kr";
    
    private IamPort iamPort;
    
    private String accessToken;
    
    private IamPortAccessToken iamPortAccessToken;
    private String apiKey;
    private String apiSecret;
    
    public IamPort(String apiKey, String apiSecret) {
        this.apiKey = apiKey;
        this.apiSecret = apiSecret;
    }
    
    public String issueAccessToken() {
        RestTemplate restTemplate = new RestTemplate();
    
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
    
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
    
        params.add("imp_key", apiKey);
        params.add("imp_secret", apiSecret);
    
        HttpEntity<MultiValueMap<String, String>> body = new HttpEntity<>(params, headers);
    
        try {
            IamPortAccessToken iamPortAccessToken = restTemplate.postForObject(new URI(HOST + "/users/getToken"), body, IamPortAccessToken.class);
    
            return iamPortAccessToken.getResponse().getAccess_token();
    
        } catch (RestClientException e) {
            throw new IamPortAccessTokenException(e);
    
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }

    이 때 IamPortAccessToken은 아래와 같고,

    public class IamPortAccessToken {
        private Integer code;
    
        private String message;
    
        private IamPortAccessTokenResponse response;
    
        public Integer getCode() {
            return code;
        }
    
        public String getMessage() {
            return message;
        }
    
        public IamPortAccessTokenResponse getResponse() {
            return response;
        }
    }

    IamPortAccessTokenResponse는 아래와 같다.

    public class IamPortAccessTokenResponse {
        private String access_token;
        private Integer now;
        private Integer expired_at;
    
        public String getAccess_token() {
            return access_token;
        }
    
        public Integer getNow() {
            return now;
        }
    
        public Integer getExpired_at() {
            return expired_at;
        }
    }
    

    RestTemplate에서 ResponseType의 field명들은 JSON 반환 값의 key값과 동일해야 된다.

    만약 다르게 쓰고 싶다면 @JsonProperty를 이용하면 된다.

     

    에를 들면, 

    {
      "property1": "value1",
      "property2": 42,
      "property3": ["item1", "item2", "item3"]
    }

    위와 같은 JSON에 해당하는 ResponseType은

    public class ResponseClass {
      @JsonProperty("property1")
      private String someOtherName;
      
      @JsonProperty("property2")
      private int someNumber;
      
      @JsonProperty("property3")
      private List<String> items;
    
      ...
    }

    와 같이 작성해줄 수 있다.

     

    그리고 이제 필요한 계좌 소유주를 확인을 해야하는데, get메서드로 header에 토큰을 보내야 한다.

    그런데 getForObject 메서드는 헤더를 설정해줄 수 없기 때문에 exchange를 쓸 수 밖에 없었다.

    public String getBankHolder(String bankName, String accountNumber) {
        RestTemplate restTemplate = new RestTemplate();
    
        String accessToken = issueAccessToken();
    
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Bearer " + accessToken);
    
        HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(headers);
    
        String bankCode = bankCodes.get(bankName);
    
        try {
            ResponseEntity<IamPortAccountHolder> response = restTemplate.exchange(
                    HOST + "/vbanks/holder?bank_code=" + bankCode + "&bank_num=" + accountNumber,
                    HttpMethod.GET,
                    entity,
                    IamPortAccountHolder.class);
    
            return response.getBody().getResponse().getBank_holder();
    
        } catch (RestClientException e) {
            throw new IamPortBankHolderException(e);
        }
    }

    위와 같은 코드를 통해 아임포트 API를 통해 계좌 소유주를 확인할 수 있게 되었다!

     

    외부 API를 사용할 때는 API문서를 확인해보고, network 탭을 열어서 실제로 어떻게 주고 받는지 확인을 하고, 

    httpie등의 도구로 실제로 요청을 해본 뒤에 코드를 작성하는 것이 가장 확실하고 빠르게 작업할 수 있는 방법인 것 같다.

    API 문서만 보고 RestTemplate을 쓰면 안될 때 어디서부터 문제인지 파악하기가 어렵다.

    RestTemplate을 쓰기 전에 먼저 요청 방식을 꼭 완벽히 확인하자!

     

    댓글

Designed by Tistory.