티스토리 뷰

공공데이터 활용하기

http://www.kobis.or.kr/kobisopenapi/homepg/main/main.do

 

영화진흥위원회 오픈API

OPEN API 서비스 영화진흥위원회 영화관입장권통합전산망에서 제공하는 오픈API 서비스로 더욱 풍요롭고 편안한 영화 서비스를 즐겨보세요.

www.kobis.or.kr

 

Data가 없기 때문에 공공데이터 "영화진흥위원회_영화박스오피스 DB"에서 제공하는 API를 활용 해보도록 하겠습니다.

먼저 회원가입 후 키를 발급 받아야 합니다.

영화진흥위원회_영화박스오피스 DB

"키 발급/관리"에서 키를 발급 받습니다.

영화진흥위원회_영화박스오피스 DB

발급 받은 키는 노출되지 않도록 관리해야 합니다.

키를 발급 받았으니 어떤 API가 있는지 확인 해보겠습니다. ( OPEN API -> 제공서비스)

영화진흥위원회_영화박스오피스 DB

API에 대한 Request(요청) / Response(응답) 설명이 있습니다.

이중에서 "영화목록 API"를 사용해 볼텐데요. 아래로 내려보면 Sample Request가 있습니다.

 

* 응답 예시

XML : http://kobis.or.kr/kobisopenapi/webservice/rest/movie/searchMovieList.xml?key={키}
JSON : http://kobis.or.kr/kobisopenapi/webservice/rest/movie/searchMovieList.json?key={키}

 

lombok & jackson 설정하기
  • lombok
    • 어노테이션 기반으로 코드를 자동완성 해주는 라이브러리
  • jackson
    • Java Object를 JSON으로 변환하거나 JSON을 Java Object로 변환하는데 사용할 수 있는 Java 라이브러리
    • Stream API : 스트림 형식으로 데이터를 분석하고 생성하기 때문에 성능이 좋습니다.
    • Tree Model : XML의 DOM 처럼 Node 형태로 데이터를 다룰 수 있기 때문에 유연성이 좋습니다.
    • Data Binding : POJO 기반의 자바 객체들을 JSON으로 변환시킬 수 있습니다.

의존성을 추가 해보겠습니다.

build.gradle

build.gradle

implementation 'org.projectlombok:lombok'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.3'

 

lombok 어노테이션 참고하여 적용해보도록 하겠습니다.

어노테이션 설명 비고
@Getter

@Setter
Getter 메소드 자동 생성

Setter 메소드 자동 생성
- lazy : 지연 호출로 동기화를 이용하여 1번만 호출 (true)
- AccessLevel : 접근 제한 레벨 설정
@ToString ToString 메소드 자동 생성 - callSuper : 상위 클래스 toString 호출 여부
- includeFieldNames : 필드명 생략 여부
- exclude : 출력하지 않을 필드명 입력
@Data @Getter, @Setter, @EqaulsAndHashCode
@ToString, @RequiredArgsConstructor 자동생성  
 
@AllArgsConstructor 모든 필드를 포함한 생성자 생성  
@NoArgsConstructor 매개 변수가 없는 생성자 생성  
@RequriedArgsConstructor final 필드만 포함된 생성자 생성  
@Builder Builder 패턴 사용  
@EqualsAndHashCode equals, hashcode 메소드 자동생성 - of : 포함할 필드
- exclude : 제외할 필드
@Value 불변 선언  
@Val class로 final 키워드 대신 사용하는 변수  
@NonNull Null 일 경우 NullPointerException 발생  
@Cleanup 자동 리소스 관리로 close() 메소드 호출  
@SneakyThrows Exception 발생시 체크된 Throable로 전달  
@Synchronized 메소드 동기화 설정  
@Log 로그를 설정 - 기본 변수명 : Log
(config 파일 설정 후 명칭 변경 가능)
- 로그 종류 : @Log, @Slf4j, @CommonLog, 
Xslf4j, JBossLog 등

model.boxoffice 패키지를 생성한 후 MovieListModel Class를 만들고

Request / Response 모델에 lombok을 적용 합니다.

MovieListModel.java

MovieListModel.java

package com.api.opendata.model.boxoffice;

import lombok.*;
import java.util.ArrayList;

public class MovieListModel {
    @Getter
    @Setter
    static public class MovieListRequest{
        private String curPage;
        private String itemPerPage;
        private String movieNm;
        private String directorNm;
        private String openStartDt;
        private String openEndDt;
        private String prdtStartYear;
        private String prdtEndYear;
        private String repNationCd;
        private String movieTypeCd;
    }

    @Getter
    @Setter
    static public class MovieListResponse
    {
        private MovieListResult movieListResult;
    }

    @Getter
    @Setter
    static public class MovieListResult
    {
        private int totCnt;
        private String source;
        private ArrayList<Movie> movieList;
    }

    @Getter
    @Setter
    static public class Movie
    {
        private String movieCd;
        private String movieNm;
        private String movieNmEn;
        private String prdtYear;
        private String openDt;
        private String typeNm;
        private String prdtStatNm;
        private String nationAlt;
        private String genreAlt;
        private String repNationNm;
        private String repGenreNm;
        private ArrayList<Director> directors;
        private ArrayList<Company> companys;
    }

    @Getter
    @Setter
    static public class Director
    {
        private String peopleNm;
    }

    @Getter
    @Setter
    static public class Company
    {
        private String companyCd;
        private String companyNm;
    }
}

 

공공데이터 API 통신 & 모델 바인딩

공공데이터 API와 모델이 준비되었으니 사용해봐야겠죠?

공공데이터 API를 통신하고 Response(응답)받아 모델에 바인딩한 다음 필요한 정보만 추출해 보겠습니다.

 

먼저 프로젝트 구성은 아래와 같이 구성합니다.

  • common.util > Utility : Http통신과 같은 유틸리티
  • controller > BoxOfficeController : RestAPI 컨트롤러
  • model.boxoffice > MovieListModel : Request / Response 모델
  • process > BoxOffice : 공공데이터 API 통신 및 모델 바인딩
  • service > BoxOfficeService : 공공데이터 API Response 가공

프로젝트 구성

프로젝트 구성이 끝났으면 소스코드 작성 후 결과를 확인 해보겠습니다.

 

BoxOfficeController.java

package com.api.opendata.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.api.opendata.service.BoxOfficeService;
import java.util.HashMap;

/*
 * 영화박스오피스 DB (일 3000회 제한)
 * 일별 박스오피스
 * 주간/주말 박스오피스
 * 공통코드 조회
 * 영화목록
 * 영화 상세정보
 * 영화사목록
 * 영화사 상세정보
 * 영화인목록
 * 영화인 상세정보
 */

@RestController
@RequestMapping("/api/boxoffice/*")
public class BoxOfficeController {
    @Autowired
    private BoxOfficeService boxOfficeService;

    @RequestMapping("/search")
    public HashMap<String, String> SearchBoxOffice(@RequestParam String targetDt)
    {
        HashMap<String, String> result;

        result = boxOfficeService.RunSearch(targetDt);

        return result;
    }
}

 

BoxOfficeService.java

package com.api.opendata.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.api.opendata.common.util.Utility;
import com.api.opendata.model.boxoffice.*;
import com.api.opendata.process.BoxOffice;
import java.util.HashMap;

@Service
public class BoxOfficeService {
    @Autowired
    private BoxOffice boxOffice;

    public HashMap<String, String> RunSearch(String targetDt)
    {
        MovieListModel.MovieListRequest movieListRequest = new MovieListModel.MovieListRequest();
        MovieListModel.MovieListResponse movieListResponse = null;

        HashMap<String, String> result = new HashMap<String, String>();

        try{
            //movieListRequest.setRepNationCd("22041011"); //한국
            movieListRequest.setMovieTypeCd("220101"); //장편
            movieListResponse = boxOffice.SearchMovieList(movieListRequest);

            result.put("MovieList", MovieListCard(movieListResponse));
        }catch (Exception e){
        }

        return result;
    }

	public String MovieListCard(MovieListModel.MovieListResponse movieListResponse){
        StringBuffer movieListCard = new StringBuffer();

        for(MovieListModel.Movie movie : movieListResponse.getMovieListResult().getMovieList()){
            // 대표장르 | 영화명
            movieListCard.append(movie.getRepGenreNm()  + " | " + movie.getMovieNm());

            movieListCard.append(System.lineSeparator());
        }

        return movieListCard.toString();
    }
}

 

BoxOffice.java

package com.api.opendata.process;

import org.springframework.stereotype.Service;
import com.api.opendata.common.util.Utility;
import com.api.opendata.model.boxoffice.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

@Service
public class BoxOffice {
    static String _url = "http://kobis.or.kr";
    static final String _key = {발급키};

    public MovieListModel.MovieListResponse SearchMovieList(MovieListModel.MovieListRequest movieListRequest) throws JsonProcessingException
    {
        ObjectMapper objectMapper = new ObjectMapper();
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        String urlPath = "/kobisopenapi/webservice/rest/movie/searchMovieList.json";
        String result = "";
        MovieListModel.MovieListResponse response= null;

        params.add("key", _key);
        params.add("repNationCd", movieListRequest.getRepNationCd());
        params.add("movieTypeCd", movieListRequest.getMovieTypeCd());

        result = Utility.GetHttp(_url, urlPath, params);

        response = objectMapper.readValue(result, MovieListModel.MovieListResponse.class);

        return response;
    }
}

 

Utility.java

package com.api.opendata.common.util;

import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.client.WebClient;

import java.text.DecimalFormat;

public class Utility {

    static public String GetHttp(String url, String urlPath, MultiValueMap<String, String> params){

        WebClient client = WebClient.builder()
                .baseUrl(url)
                //.defaultCookie("cookieKey", "cookieValue")
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .build();

        String result = client.get()
                            .uri(uriBuilder  -> uriBuilder
                                    .path(urlPath)
                                    .queryParams(params)
                                    .build())
                            .retrieve()
                            .bodyToMono(String.class)
                            .block();

        return result;
    }

    static public Object GetDecimalFormat(String value, String format){
        DecimalFormat decimalFormat = new DecimalFormat(format);

        return decimalFormat.format(Integer.parseInt(value));
    }
}

 

코드 작성이 끝났다면 호출해 보도록 하겠습니다.

http://localhost:8080/api/boxoffice/search?targetDt=20220815

응답 결과

 

댓글
최근에 올라온 글
TAG
more
글 보관함
«   2024/05   »
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