티스토리 뷰
공공데이터 활용하기
http://www.kobis.or.kr/kobisopenapi/homepg/main/main.do
영화진흥위원회 오픈API
OPEN API 서비스 영화진흥위원회 영화관입장권통합전산망에서 제공하는 오픈API 서비스로 더욱 풍요롭고 편안한 영화 서비스를 즐겨보세요.
www.kobis.or.kr
Data가 없기 때문에 공공데이터 "영화진흥위원회_영화박스오피스 DB"에서 제공하는 API를 활용 해보도록 하겠습니다.
먼저 회원가입 후 키를 발급 받아야 합니다.
"키 발급/관리"에서 키를 발급 받습니다.
발급 받은 키는 노출되지 않도록 관리해야 합니다.
키를 발급 받았으니 어떤 API가 있는지 확인 해보겠습니다. ( OPEN API -> 제공서비스)
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
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
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
'IT > Spring' 카테고리의 다른 글
[Spring] SpringBoot + MariaDB JPA (0) | 2022.08.26 |
---|---|
[Spring] SpringBoot + MariaDB JDBC && MyBatis with Docker (0) | 2022.08.24 |
[Spring] Spring Boot + Java SE 17 설정 with IntelliJ (0) | 2022.08.10 |
[Spring] Java SE 17 설치 및 환경 설정 (1) | 2022.08.09 |
[Spring] SpringBoot + React 퀵 스타트 with Gradle (0) | 2022.08.09 |