오늘은 springboot를 기반으로 웹서버를 생성한 후 API를 호출해 데이터를 전달 받아 화면에 출력해보도록 하겠습니다.

 

Springboot 기본 설정은 아래 URL에서 확인 부탁드립니다.

 

인텔리J에서 Springboot 올리기 10분컷!

 

intellij SpringBoot(인텔리제이 스프링부트) 시작하기 - hello world 브라우저에 출력하기(gradle)

intellij SpringBoot(스프링부트) hello world 출력하기 @intellij 기준으로 진행하겠습니다 @Gradle 프로젝트로 진행하는 이유는 빌드 속도도 maven보다 빠르고 import 라이브러리도 한눈에 볼 수 있어 개발시에..

vmpo.tistory.com

 

#Resttemplate 이란?


Resttemplate은 간편하게 Rest 방식 api를 호출할 수 있는 spring 내장 클래스 입니다.

Spring 3.0부터 지원 가능합니다.

json , xml응답을 모두 받을 수 있습니다.

 

 

#Resttemplate 사용법


테스트 API호출 샘플로,

http://localhost:8080/GetkobisData를 호출하면 영진위(영화진흥위원회) 일별박스오피스 데이터가 출력되도록 해보겠습니다.

 

영진위 사이트에 들어가보면 오픈API 형태로 영화관련 정보를 제공하고 있습니다. 

아래 URL에 접속해보시면 일별박스 오피스 정보를 확인 할 수 있는 api 상세 스펙 확인이 가능합니다.

http://www.kobis.or.kr/kobisopenapi/homepg/apiservice/searchServiceInfo.do?serviceId=searchMovieList

 

영화진흥위원회 오픈API

 

www.kobis.or.kr

 

샘플로 아래 API을 활용해 보겠습니다. 아래 URL을 브라우저에 입력하면 JSON형태의 데이터 확인이 가능합니다.

그럼 시작해보겠습니다.

http://www.kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=430156241533f1d058c603178cc3ca0e&targetDt=20120101

 

#builde.gradle 라이브러리 추가

 

먼저 gradle 스크립트부분을 확인해보겠습니다.

builde.gradle 파일을 열어서 아래와 같이 dependencies를 추가해 줍니다. 

(복사 그대로 하셔도 됩니다)

 

maven으로 진행하시는 경우에도 같은 라이브러리명을 pom.xml에 추가하면 됩니다.

어차피 resttemplate 코드 작성은 동일합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
dependencies {

 
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.9.3'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.3'
    compile group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
    compile group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1'
}
 

 

#실제 호출 로직 구현하기

 

아래는 Resttemplate 테스트를 위해 아래 프로젝트 구조와 같이 RestAPI.java파일을 하나 생성합니다.

 

아래 처럼 callAPI() 메소드를 하나 만들어주고 

class명 위에는 @RestController, 메소드 위에는 @GetMapping("GetkobisData") 어노테이션을 추가해줍니다.

이제 기본 골격이 나왔습니다. 

내부 로직만 구현하면됩니다.

 

RestTemplate 객체를 하나 생성해야 합니다. 이 생성된 객체로 api를 호출하게 됩니다.

아래처럼 RestTemplate객체를 하나 생성해줍니다. 

 

HttpComponentsClientHttpRequestFactory 객체를 통해 타임아웃을 제어 할 수 있습니다.

RestTemplate resttemplate = new RestTemplate()  -> 타임아웃이 필요없다면, 왼쪽같이 생성해도 상관없습니다.

본격적으로 데이터를 호출해보도록 하겠습니다. 

header 클래를 정의해주고, url를 정의해주고 restTemplate.exchange() 메소드로 api를 호출하게 됩니다.

전달 받는 값은 json 형태로이므로 

string 자체로 받아 파싱을 해도됩니다.

resttemplate의 경우 편리하게도 map, 사용자가 정의한 class 등 다양한 형태로 데이터를 바로 파싱해서 받을 수 있습니다. 

 

아래 처럼 정의해주면 됩니다.

ResponseEntity<원하는 클래스 타입> resultMap = restTemplate.exchange(uri.toString(), HttpMethod.GET, entity, 원하는클래스타입.class);

 

호출 결과로 http status code, 헤더 정보, 실제 데이터가 존재하는 body정보를 확인 할 수 있습니다.

 

restTemplate.exchange() 함수의 파라미터중 HttpMethod.XXX 부분을

HttpMethod.GET HttpMethod.POST , HttpMethod.DELETE형태로 바꿔주면 해당 방식으로 호출을 할 수 있습니다.

*전체 코드 샘플

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package com.supercoding.resttemplate.RestApi;
 
import com.fasterxml.jackson.databind.ObjectMapper;
 
 
@RestController
public class RestAPI {
 
    @GetMapping("/GetkobisData")
    public String callAPI() throws JsonProcessingException {
 
        HashMap<String, Object> result = new HashMap<String, Object>();
 
        String jsonInString = "";
 
        try {
 
            HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
            factory.setConnectTimeout(5000); //타임아웃 설정 5초
            factory.setReadTimeout(5000);//타임아웃 설정 5초
            RestTemplate restTemplate = new RestTemplate(factory);
 
            HttpHeaders header = new HttpHeaders();
            HttpEntity<?> entity = new HttpEntity<>(header);
 
 
            UriComponents uri = UriComponentsBuilder.fromHttpUrl(url+"?"+"key=430156241533f1d058c603178cc3ca0e&targetDt=20120101").build();
 
            //이 한줄의 코드로 API를 호출해 MAP타입으로 전달 받는다.
            ResponseEntity<Map> resultMap = restTemplate.exchange(uri.toString(), HttpMethod.GET, entity, Map.class);
            result.put("statusCode", resultMap.getStatusCodeValue()); //http status code를 확인
            result.put("header", resultMap.getHeaders()); //헤더 정보 확인
            result.put("body", resultMap.getBody()); //실제 데이터 정보 확인
 
            //데이터를 제대로 전달 받았는지 확인 string형태로 파싱해줌
            ObjectMapper mapper = new ObjectMapper();
            jsonInString = mapper.writeValueAsString(resultMap.getBody());
 
        } catch (HttpClientErrorException | HttpServerErrorException e) {
            result.put("statusCode", e.getRawStatusCode());
            result.put("body"  , e.getStatusText());
            System.out.println("dfdfdfdf");
            System.out.println(e.toString());
 
        } catch (Exception e) {
            result.put("statusCode""999");
            result.put("body"  , "excpetion오류");
            System.out.println(e.toString());
        }
 
        return jsonInString;
 
    }
 
}
 

 

그럼 한 번 실제 실행을 해보도록 하겠습니다.

 

빌드를 하고, 아래 url을 브라우저에 입력해보면 데이터를 정상적으로 호출한 것을 알 수 있습니다.

http://localhost:8080/GetkobisData

#디버깅으로 데이터 확인하기


디버깅을 걸어보겠습니다.

resultMap에 데이터가 정상적으로 파싱 되어 map형태로 변수에 값이 저장된 것을 알 수 있습니다.

 

#원하는 데이터만 뽑아내기 (순번, 영화명)


그럼, 일별 박스오피스 정보 순번이랑, 영화명만 추출해보겠습니다.

데이터는 정상적으로 조회되니 파싱해서 바로 위 캡처화면의 movieNm 변수만 발라내면 되겠네요.

 

가보죠.

 

resttemplate.exchange() 메소드 호출 이후 코드를 아래와 같이 바꿔주면 되겠네요.

리턴 받은 응답값이 json형태이기 때문에 map형태로 받아 각 key값을 접근해가면서 영화명까지 접근한 코드입니다.

 

[각 라인별 설명]

LinkedHashMap lm = (LinkedHashMap)resultMap.getBody().get("boxOfficeResult");

: 전체 정보를 담는 "boxOfficeResult" 의 value 접근

 

ArrayList<Map> dboxoffList = (ArrayList<Map>)lm.get("dailyBoxOfficeList");

:영화 정보 리스트를 담고 있는 "dailyBoxOfficeList"의 value 접근 (list형태임)

 

LinkedHashMap mnList = new LinkedHashMap<>();
for (Map obj : dboxoffList) {

mnList.put(obj.get("rnum"),obj.get("movieNm"));
}

ObjectMapper mapper = new ObjectMapper();
jsonInString = mapper.writeValueAsString(mnList);
:for문으로 원하는 정보를 조회

 

자 이제 다시 빌드를 하고 데이터를 호출해보면 

아래와 같이 순번과, 영화명만 조회가 됩니다.

 

이제 다른 API도 같은 방식으로 파싱해서 데이터를 전달 받은 후 원하는 데이터만 추출하면 되겠네요!

 

 

*최종 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package com.supercoding.resttemplate.RestApi;
 
import com.fasterxml.jackson.databind.ObjectMapper;
 
 
@RestController
public class RestAPI {
 
    @GetMapping("/GetkobisData")
    public String callAPI() {
 
        HashMap<String, Object> result = new HashMap<String, Object>();
 
        String jsonInString = "";
 
        try {
 
            HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
            factory.setConnectTimeout(5000); //타임아웃 설정 5초
            factory.setReadTimeout(5000);//타임아웃 설정 5초
            RestTemplate restTemplate = new RestTemplate(factory);
 
            HttpHeaders header = new HttpHeaders();
            HttpEntity<?> entity = new HttpEntity<>(header);
 
 
            UriComponents uri = UriComponentsBuilder.fromHttpUrl(url+"?"+"key=430156241533f1d058c603178cc3ca0e&targetDt=20120101").build();
 
            //이 한줄의 코드로 API를 호출해 MAP타입으로 전달 받는다.
            ResponseEntity<Map> resultMap = restTemplate.exchange(uri.toString(), HttpMethod.GET, entity, Map.class);
 
            result.put("statusCode", resultMap.getStatusCodeValue()); //http status code를 확인
            result.put("header", resultMap.getHeaders()); //헤더 정보 확인
            result.put("body", resultMap.getBody()); //실제 데이터 정보 확인
 
            LinkedHashMap lm = (LinkedHashMap)resultMap.getBody().get("boxOfficeResult");
            ArrayList<Map> dboxoffList = (ArrayList<Map>)lm.get("dailyBoxOfficeList");
            LinkedHashMap mnList = new LinkedHashMap<>();
            for (Map obj : dboxoffList) {
                mnList.put(obj.get("rnum"),obj.get("movieNm"));
            }
            ObjectMapper mapper = new ObjectMapper();
            jsonInString = mapper.writeValueAsString(mnList);
 
        } catch (HttpClientErrorException | HttpServerErrorException e) {
            result.put("statusCode", e.getRawStatusCode());
            result.put("body"  , e.getStatusText());
            System.out.println("dfdfdfdf");
            System.out.println(e.toString());
 
        } catch (Exception e) {
            result.put("statusCode""999");
            result.put("body"  , "excpetion오류");
            System.out.println(e.toString());
        }
 
        return jsonInString;
 
    }
 
}
 
 

 

다음 포스팅에서는 XML파싱 방법과 exchange() 메소드 말고 다른 방식으로 호출하는 샘플을 확인해보겠습니다.

LIST
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기