https://developers.kakao.com/docs/latest/ko/daum-search/dev-guide#search-book
이걸 써보려고 한다.
일단 시작전에 postman으로 api를 실행해보겠다.
Auth에서 저렇게 설정하고 send 해보면
잘 나온다. 이제 이걸 적용하는게 문제다.
이런저런 구글링을 하니까 RestTemplate라는걸 사용하면 스프링에서 Rest Api를 호출할 수 있나보다.
https://spring.io/guides/gs/consuming-rest/
뭔소리여
https://hyeonyeee.tistory.com/34
https://recordsoflife.tistory.com/360
이런 저런 블로그를 찾아봤고...
package jpa.myunjuk.common;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import java.util.Map;
@RestController
public class KakaoApi {
private final String url = "https://dapi.kakao.com/v3/search/book";
private final String key = "rest api key";
@GetMapping("/kakao")
public Map callApi(@RequestParam String query){
RestTemplate restTemplate = new RestTemplate();
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.set("Authorization", "KakaoAK "+key);
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url).queryParam("query", query);
HttpEntity<String> entity = new HttpEntity<>(httpHeaders);
return restTemplate.exchange(builder.toUriString(), HttpMethod.GET, entity, Map.class).getBody();
}
}
여기까지 했다. 설명은 이따가 하기로 하고...
잘 나오긴 하는데 한글이 깨진다.
악 됐다!
https://cultist-tp.tistory.com/entry/Spring-RestTemplate-%EA%B0%9D%EC%B2%B4-%EC%82%AC%EC%9A%A9%EC%8B%9C-url%EC%97%90-%ED%8C%8C%EB%9D%BC%EB%AF%B8%ED%84%B0-%EC%A0%84%EB%8B%AC-%EB%B0%A9%EB%B2%95
여기 보고 해결했다.
package jpa.myunjuk.common;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Map;
@RestController
public class KakaoApi {
@Value("${kakao.key}")
private String key;
private String url = "https://dapi.kakao.com/v3/search/book";
@GetMapping("/kakao")
public Map callApi(@RequestParam String query) {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.set("Authorization", "KakaoAK " + key); //Authorization 설정
HttpEntity<String> httpEntity = new HttpEntity<>(httpHeaders); //엔티티로 만들기
URI targetUrl = UriComponentsBuilder
.fromUriString(url) //기본 url
.queryParam("query", query) //인자
.build()
.encode(StandardCharsets.UTF_8) //인코딩
.toUri();
//GetForObject는 헤더를 정의할 수 없음
ResponseEntity<Map> result = restTemplate.exchange(targetUrl, HttpMethod.GET, httpEntity, Map.class);
return result.getBody(); //내용 반환
}
}
에러 핸들링을 안해서 코드가 짧다. 해야지...해야 하는데...
아무튼 대충 설명하면
@Value("${kakao.key}")
private String key;
private String url = "https://dapi.kakao.com/v3/search/book";
일단 검색해본 결과 괜찮다곤 했는데, 키를 노출하는게 영 찝찝해서 application.yml에 api key를 보관했다.
application.yml
kakao:
key: key 내용
이런식으로 하고 저렇게 value 어노테이션으로 호출하면 된다.
@GetMapping("/kakao")
public Map callApi(@RequestParam String query) {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.set("Authorization", "KakaoAK " + key); //Authorization 설정
HttpEntity<String> httpEntity = new HttpEntity<>(httpHeaders); //엔티티로 만들기
URI targetUrl = UriComponentsBuilder
.fromUriString(url) //기본 url
.queryParam("query", query) //인자
.build()
.encode(StandardCharsets.UTF_8) //인코딩
.toUri();
//GetForObject는 헤더를 정의할 수 없음
ResponseEntity<Map> result = restTemplate.exchange(targetUrl, HttpMethod.GET, httpEntity, Map.class);
return result.getBody(); //내용 반환
}
그리고 여긴 실제로 구현할 땐 Service로 바꾸겠지만 일단 테스트라 API로 만들어서 바로 호출했다.
RestTemplate restTemplate = new RestTemplate();
HttpHeaders httpHeaders = new HttpHeaders();
RestTemplate는 기본이고, HttpHeaders는 Authorization 때문에 추가했다.
httpHeaders.set("Authorization", "KakaoAK " + key); //Authorization 설정
HttpEntity<String> httpEntity = new HttpEntity<>(httpHeaders); //엔티티로 만들기
저기 써있는데로 헤더에 인증 정보를 입력하고, 엔티티로 만들어 준다. post 호출일 때는 엔티티에 body도 넘긴다고 한 것 같다.
URI targetUrl = UriComponentsBuilder
.fromUriString(url) //기본 url
.queryParam("query", query) //인자
.build()
.encode(StandardCharsets.UTF_8) //인코딩
.toUri();
그리고 요청을 보낼 uri를 만든다. 개발가이드 보면 인자는 query로 넘겨야 한다. 그래서 그렇게 넘긴 것이다.
UTF-8로 인코딩하면 한글이 깨지지 않는다.
//GetForObject는 헤더를 정의할 수 없음
ResponseEntity<Map> result = restTemplate.exchange(targetUrl, HttpMethod.GET, httpEntity, Map.class);
return result.getBody(); //내용 반환
마지막으로 exchange 메소드를 이용해서 호출하면 된다.
getHeader()를 하면 헤더 정보가 나오고 getBody()를 하면 내용이 반환되는가보다.
인텔리제이피셜 넘겨야하는 인자는 위와 같다.
아무튼 잘 나온다!
하지만 여기서 끝난게 아니고 이 결과를 담을 Dto도 만들어야 하고 뭐 암튼 이것저것 할 것들이 많다.