
과제 설명
목적
카카오 로컬 REST API 중 키워드로 장소 검색하기, 카데고리로 장소 검색하기 API를 활용하여 자신을 위치를 기반으로 특정 위치 내의 장소를 검색하는 java 애플리케이션을 개발합니다.
작업 옵션
- 지정된 반경 내에서 주유소를 검색
- 지정된 반경 내에서 약국을 검색 ✅
구현 내용
- 카카오 API 키 획득
- 카카오 개발자에 로그인하여 어플리케이션 생성
- 생성한 어플리케이션의 REST API 메모
- 로컬 REST API 사용
- 지도/로컬 중 로컬 REST API문서를 참고하여 키워드로 장소 검색하기와 카테고리로 장소 검색하기를 활용하여 개발
- 요청과 응답 구조에 대한 예제 코드를 확인하여 개발한다.
- JAVA 어플리케이션 구현
- 특정 위치 키워드, 검색 반경 입력
- 이를 기반으로 위도, 경도 추출 → 키워드로 장소 검색하기 api사용
- 해당 위도,경도 반경 내의 약국 검색 → 카테고리로 장소 검색하기 api사용
- 검색 결과(JSON)에서 원하는 정보 추출 → 카테고리로 장소 검색하기 api사용
- 상위 10개 결과 표시
- 장소 URL 재 입력시, 해당 kakaomap이 출력 → Desktop api사용
- exit시, 종료
GET
키워드로 장소 검색하기 - URL : https://dapi.kakao.com/v2/local/search/keyword.json (JSON 응답요청)
└ Static으로 URL값을 저장해둔다.
- 헤더 : Authorization: KakaoAK ${REST_API_KEY}
└ src/main/resources/application.properties에 REST_API값 숨겨둔다.
REST_API_KEY와 같은 개인키는 github와 같은 공유공간에 업로드하면 안되므로, .gitignore에 적어 비공개로 해야한다. (과제를 위해 예외적으로 공개했다.)
public static void getAPIKey() throws IOException { Properties pro = new Properties(); FileInputStream fis = new FileInputStream(PROPERTIES); pro.load(new BufferedInputStream(fis)); REST_API_KEY = pro.getProperty("REST_API"); }
- Request
HttpUriRequest request = RequestBuilder.get() .setUri(GET_ADDRESS_BY_KEYWORD_URL) .setHeader("Authorization", REST_API_KEY) .addParameter("query", arrival) .build();
위치를 입력하여 쿼리로 request를 보낸다.
- Response
JSONObject resJsonObj = new JSONObject(responseSb.toString()); JSONArray resJsonArr = resJsonObj.getJSONArray("documents"); JSONObject subJsonObj = new JSONObject(resJsonArr.get(0).toString()); x = subJsonObj.getString("x"); y = subJsonObj.getString("y");
JSON으로 받은 여러 응답값 중 x(경도), y(위도)를 파싱하여 변수에 저장한다.
GET
카테고리로 장소 검색하기 - URL : https://dapi.kakao.com/v2/local/search/category.json (JSON 응답요청)
└ 위 API와 동일하게 사용
- 헤더 : Authorization: KakaoAK ${REST_API_KEY}
└ 위 API와 동일하게 사용
- Request
HttpUriRequest request = RequestBuilder.get()
.setUri(GET_ADDRESS_BY_CATEGORY_URL)
.setHeader("Authorization", REST_API_KEY)
.addParameter("query", "약국")
.addParameter("category_group_code", "PM9")
.addParameter("x", x)
.addParameter("y", y)
.addParameter("radius", String.valueOf(radius))
.addParameter("size", String.valueOf(10))
.build();
입력한 위치와 반경을 기반으로 10개의 “약국”을 요청하는 request를 보낸다.
- Response
JSONObject resJsonObj = new JSONObject(responseSb.toString());
JSONArray resJsonArr = resJsonObj.getJSONArray("documents");
int cnt = 0;
for (int i = 0; i < 10; i++) {
JSONObject subJsonObj = resJsonArr.getJSONObject(i);
String placeUrl = subJsonObj.getString("place_url");
String placeName = subJsonObj.getString("place_name");
String addressName = subJsonObj.getString("address_name");
String phone = subJsonObj.getString("phone");
String distance = subJsonObj.getString("distance");
PlaceInformation place = new PlaceInformation(placeUrl, placeName, addressName, phone, distance);
placeList.add(place);
}
- JSON으로 받은 여러 응답값 중 장소 URL(place_url), 상호명(place_name), 전화번호(phone), 거리(distance)를 파싱하여 변수에 저장한다.
- 해당 정보들을 place라는 하나의 객체로 형성하여 placeList에 담아둔다.
public static void runUrl() throws IOException, URISyntaxException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while (true) {
System.out.print("kakomap URL(장소URL):");
String URL = br.readLine();
if (URL.equals("exit")) {
break;
} else {
Desktop.getDesktop().browse(new URI(URL));
}
}
System.out.println("프로그램 종료");
}
kakaoMap URL을 입력하여 브라우저를 실행시키기 위해 Desktop API를 활용한다.
입출력화면
개인 공부 정리
- HttpClient를 이용한 Request, Response 연동
- HttpClient를 사용하려면 dependency에 apache를 설정 (버전에 맞춰 생성)
- HttpClient 인스턴스 생성
CloseableHttpClient client = HttpClients.
custom
().build();
- HttpRequest 생성 (Uri, Header, Parameter을 정의하여 build)
HttpUriRequest request = RequestBuilder.
get
().setUri().setHeader().addParameter().build()
- HttpResponse 회수 w/ IOException
CloseableHttpResponse response = client.execute(request);
- Response String화
BufferedReader reader = new BufferedReader(new InputStreamReader (response.getEntity().getContent())); String input; StringBuffer responseSb = new StringBuffer(); while ((input = reader.readLine()) != null) { responseSb.append(input); } reader.close(); client.close();
- Response(JSON) 파싱
❓CloseableHttpClient 와 HttpClient의 차이점CloseableHttpClient
: Apache HttpClient 4.3 이상에서 새롭게 추가된 클래스- HttpClient기능 확장 : close메소드를 제공하여 HttpClient 인스턴스의 연결을 닫을 수 있다.
- Http 통신 가능 회수 : 각 커넥션을 제대로 닫지 않으면 일정 횧수 이상 HTTP통신이 불가능
⇒ HttpClient를 하면 close_wait, time_wait이 없어지지 않고 계속 쌓이는 문제점이 발생할 수 있으므로 CloseableHttpClient를 쓰는것을 권고한다.
- JSON 형식 이해 및 파싱방법
처음에 JSONObject, JSONArray간의 차이가 혼동되어 개발할 때 어려움이 있었다.
JSONObject
: { }로 묶인 구조로, 하나 이상의 key-value 쌍을 담고 있는 객체 구조
JSONArray
: [ ]로 묶인 구조로, 문자열, 숫자, 배열 객체 등을 담을 수 있는 구조
example
"Book" : [ { "Name" : "자바", "Author" : "김철수", "Price" : 15000 }, { "Name" : "오라클", "Author" : "박최현", "Price" : 20000 }, { " Name" : "스프링", "Author" : "박승진", "Price" : 38000 }]
- key : “Book”
- Object : { }안에 key-value들이 묶인 구조
{ "Name" : "자바", "Author" : "김철수", "Price" : 15000 },
- Value : Object들이 배열로 들어간 형태
실전적용
- Desktop API 활용
Desktop.
getDesktop
().browse(new URI(URL));
단, URL은 http://를 꼭 붙어야 에러가 나지 않는다.
회고 및 고찰
https://github.com/YurimYang/Location-Based-Place-Search-Java-Application
이전 학기 전공 수업을 들으며 네이버 클로바의 OCR API를 적용한 웹페이지를 제작한 경험이 있다.
해당 과정에서 외부 API를 연동하기 위해 HttpUrlConnection을 사용하여 Http 통신을 했었고 전달받은 JSON을 파싱하여 데이터를 DB에 저장하는 작업을 맡았었다.
이번 과제에서는 Http 통신 중 HttpClient통신을 사용해봤는데 HttpUrlConnection보다 다양한 API를 사용하지만 상대적으로 무거운 느낌이었다.
다양한 Http통신 중 개발자가 선택해야하기 때문에 프로젝트에 적합한 통신 방법을 검토후에 적용해봐야겠다.
[GITHUB Issue]
추가적으로, github에서 history 충돌이 나는 문제를 겼었다.
제공해준 github의 main브랜치를 clone을 받은 뒤, 해당 폴더 내부에서 작업을 한 뒤, 개인 브랜치에 push를 했어야 했다.
하지만 해당 폴더 내부가 아닌 내가 만든 폴더에서 개발을 하니, push origin 개인브랜치 까지는 가능했지만 PULL-REQUEST가 되지 않았다.

문제점을 인식하지 못한채 해결하기 위해, 로컬에서 프로젝트를 재 생성하고 같은 방식으로 브랜치를 만들어 pull-request를 했으나 또,,,똑같은 문제였다.
그때부터 intelliJ의 git graph를 확인하면서 문제점을 찾기 시작했고, 클론받은 폴더 내부에서 작업을 한뒤, push를 해야지만 history이력이 같아짐을 확인할 수 있었다.
과제로 제출해야하는 모든 폴더들을 clone받은 폴더 내부로 옮긴 뒤, PULL-REQUEST를 하고 이를 마무리했다.

Uploaded by N2T