JAVA/요점정리

[스프링부트] 외부(이카운트) API 연동하여 데이터 통신 feat:HttpUrlConnection

진짠 2023. 12. 8. 18:41
728x90
서론

 

업무 중 외부 API 연동해야 하는 일이 생겼다. 원래라면 만들어둔 소스를 갔다 쓸텐데 Content-Type 관련해서 맞지 않는지 제대로 작동하지 않아서 직접 만들어썼다(라고 말하고 다른 프로젝트에 있던 소스 커스텀만 한거지만).

기능들에 대해 간단히 정리하고 기억하기 위해서 포스팅을 한다.

 

(더 간단하고 쉽거나 효율적인 방법이 있을 수 있으므로 참고만 하시길.)

 

외부 API 연동관련 정보

 

연동하기 위해선 몇가지 알아야할 정보가 있다. 나같은 경우 재고관리를 위해 이카운트API라는 것을 사용해야 했고 해당 안내페이지에서 찾을 수 있었다. 다른 API도 홈페이지에 들어가보면 연동에 필요한 기본 정보를 제공하고 있을 것이다.

 

(혹시 모르니 이카운트 URL을 남겨둔다.)

 

https://sboapi.ecount.com/ECERP/OAPI/OAPIView?lan_type=ko-KR

이카운트 오픈 API 란? 고객사(개발자)가 이카운트와 타 사이트 및 프로그램과의 연동 기능을 개발할 수 있도록 [이카운트의 데이터 플랫폼을 외부에 공개]하는 서비스 입니다. 개발단계 [이카운

sboapi.ecount.com

 

연동 전 필요한 절차나 상태코드, 오류에 대한 설명이나 주의사항을 숙지까지는 못하더라도 훑고 지나가는게 좋다. 어차피 제대로 연동안하면 오류메시지 뜰 테니까.

 

이카운트 API의 경우 필요 API를 연동하기 전에 로그인 절차를 통해 세션ID를 받아온다. 파라미터로 세션 ID를 넘겨줘야 다른 API도 이도이 가능하다. 연동 전 사전작업에 대한 숙지가 필요하다고 느꼈다.

 

HttpUrlConnection

 

여러가지 방법이 있겠지만 나의 경우 HttpUrlConnection 클래스를 사용해 연동을 했다. URLConnection의 서브클래스로 다음과 같은 단계를 따른다고 한다.

 

URL 객체 만들기

URL 에서 URLConnection 객체 얻기

URL 연결 구성

헤더 필드 읽기

입력 스트림 가져오기 및 데이터 읽기

출력 스트림 가져오기 및 데이터 쓰기

연결 닫기

 

출처 : https://blueyikim.tistory.com/2199

 

다음과 같은 단계를 통해 API를 연동할 것이다.

 

URL url = new URL(saveSaleOrderUrl); // URL 객체 생성
HttpURLConnection conn = (HttpURLConnection)url.openConnection(); // 서버 연결
conn.setDoOutput(true); // OutputStream 으로 데이터를 넘겨주는 옵션
conn.setRequestMethod("POST"); // 요청 방식을 POST로 넘겨준다.
conn.setRequestProperty("Content-Type", "application/json"); // 헤더 값 세팅
conn.setRequestProperty("Accept-Charset", "UTF-8");

OutputStream os = conn.getOutputStream(); //출력 스트림 세팅
os.write(req_data.getBytes("UTF-8")); //Byte 형태 
os.flush(); //데이터 전송

 

본 단계가 외부 API에 요청(request)값을 보내는데 필요한 과정들이다.

 

saveSaleOrderUrl은 API URL 경로이며 별도로 세팅해주어야 한다.

 

HttpURLConnection은 추상 클래스로 별도의 인스턴스 세팅이 불가능하다. 연동문서를 보며 필요한 세팅을 잘 확인하자.

 

req_data 변수에는 API가 요구하는 파라미터들을 담아서 보내주었다. API마다 데이터를 받는 자료형이 조금씩 다르니 확인하고 보내야한다. (이카운트의 경우 JSONArray를 다시한번 JSONObject로 감싸서 보내주더라.)

 

flush()의 경우 스트림 형태로 데이터를 보낼 때 잔여 데이터들을 남기지 않고 보내주는 역할을 하니 빼먹지 말고 써주자.

 

BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
while ((inputLine = in.readLine()) != null) 
{
outResult.append(inputLine);
}
conn.disconnect();​

 

다음은 API 요청 후 응답(response)값을 받아오는 과정이다.

 

InputStream을 InputStreamReader 객체를 생성하여 넣어주었다. InpustStream은 int 형태로 저장되며 UTF-16 값이기 때문에 InputStreamReader을 통해 문자단위(char)로 데이터를 변환시키는 중간다리 역할을 한다.

 

마지막으로 BufferedReader를 통해 String 형으로 값을 받아올 수 있게 했으며 readeLine()을 통해 String 변수 inputLine에 값을 전달한다.

 

'StringBuffer outResult = new StringBuffer();' 형태로 선언한 변수에 append 시켜주었는데 StringBuffer 객체를 생성한 이유는 문자열 연산 등으로 변화하는 메모리 공간을 유동적으로 늘릴 수 있도록 하기 위함이다.

 

(String의 객체는 한번 생성되면 할당된 메모리 공간이 변하지 않는다. 때문에 문자열 연산이 많을 경우 기존 객체를 제거하고 가비지 컬렉션이 회수하는 형태를 띄는데 성능이 좋지 않다. 대신 간단하게 사용 가능하며 동기화에 대해 신경쓰지 않아도 돼서 내부 데이터를 자유롭게 공유 가능하다.

 

반면 StringBuffer는 문자열 연산으로 기존 객체의 공간이 부족할 경우 버퍼의 크기를 늘리며 유연하게 동작한다.

 

연산이 많을 경우 성능은 StringBuilder가 StringBuffer보다 뛰어나다고 한다.)

 

근데 왜 StringBuffer 썼냐하면 기존 소스의 영향...이 크다.

 

마지막으로 연결한 API 통신을 닫아주는 disconnect()를 잊지말자.

 

주의점?

 

외부 API 를 연동하며 주의해야할 점이 있다면 요청값을 보내기 전 Content-type 이나 요청방식(GET,POST...) 등을 잘 확인해야 하고 연동 홈페이지의 상태, 오류값을 통해 어느 부분에서 오류가 났는지 알 수 있었다.

 

막상 포스팅을 하고 보니 별 내용이 없는데 추후 다른 연동할 일이 생긴다면 지금 포스팅과 비교하며 차이점등을 써볼 계획이다.

728x90