SpringBoot로 오픈 API사용하기

후니·2023년 5월 7일

스프링

목록 보기
2/5

개요

개인 프로젝트를 진행하며 주식시세와 주식정보를 오픈API를 통해 가져오려고 하였다. 두가지 방법중 고민하였는데 하나는 증권사의 API가 있었고 공공데이터포털의 API가 있었다. 증권사의 오픈API는 계좌개설을 해야하거나 유료인 경우가 많아 공공데이터포털의 오픈API를 이용하기로 하였다

소스코드

StockIndex.java
지수정보를 받을 DTO 생성

@Data
@AllArgsConstructor
@NoArgsConstructor
public class StockIndex {
    private Float lsYrEdVsFltRt; // 지수의 전년말대비 등락율
    private String basPntm; // 지수를 산출하기 위한 기준시점
    private Integer basIdx; // 기준시점의 지수값
    private String basDt; // 기준일자
    private String idxCsf; // 지수의 분류명칭
    private String idxNm; // 지수의 명칭
    private Integer epyItmsCnt; // 지수가 채용한 종목 수
    private Float clpr; // 정규시장의 매매시간종료시까지 형성되는 최종가격
    private Float vs; // 전일 대비 등락
    private Float fltRt; // 전일 대비 등락에 따른 비율
    private Float mkp; // 정규시장의 매매시간개시후 형성되는 최초가격
    private Float hipr; // 하루 중 지수의 최고치
    private Float lopr; // 하루 중 지수의 최저치
    private Long trqu; // 지수에 포함된 종목의 거래량 총합
    private Long trPrc; // 지수에 포함된 종목의 거래대금 총합
    private Long lstgMrktTotAmt; // 지수에 포함된 종목의 시가총액
    private Integer lsYrEdVsFltRg; // 지수의 전년말대비 등락폭
    private Float yrWRcrdHgst; // 지수의 연중최고치
    private String yrWRcrdHgstDt; // 지수가 연중최고치를 기록한 날짜
    private Float yrWRcrdLwst; // 지수의 연중최저치
    private String yrWRcrdLwstDt; // 지수가 연중최저치를 기록한 날짜
}

Api.java
HTTP통신은 여러번 사용할 수 있기 때문에 class를 생성하고 callApi함수를 선언하였다
callApi함수는 http통신의 응답값을 JSONObject로 리턴하도록 했다

public class Api {
    public static JSONObject callApi(JSONObject param) {
        HttpURLConnection conn = null;
        JSONObject result = null;
        try {
            // URL 설정
            URL url = new URL(param.getString("url"));

            conn = (HttpURLConnection) url.openConnection();

            // type의 경우 POST, GET, PUT, DELETE 가능
            conn.setRequestMethod(param.getString("type"));
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setDoOutput(true);

            // 보내고 결과값 받기
            if (conn.getResponseCode() == 200) {
                BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
                StringBuilder sb = new StringBuilder();
                String line = "";
                while ((line = br.readLine()) != null) {
                    sb.append(line);
                }
                result = new JSONObject(sb.toString());
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return result;
    }
}

IndexController.java
Controller에서 Service에 코스피 차트정보를 요청한다.

// 메인페이지
    @GetMapping("/")
    public String index(HttpServletRequest request, Model model) {
        HttpSession session = request.getSession(false);
        User user = null;

        if (session != null) {
            user = (User) session.getAttribute("LOGIN_USER");
            model.addAttribute("user", user);
        }

        List<StockIndex> kospi = stockService.getStockMarketIndex("코스피"); // 코스피지수
       
        model.addAttribute("kospi", kospi);

        return "index";
    }

StockService.java
Service에서는 아까 구현한 API클래스를 통해 코스피지수 정보를 가져온다.

// 주식 지수 정보 가져온다
    public List<StockIndex> getStockMarketIndex(String idxNm) {
        // 한달전 날짜
        Calendar mon = Calendar.getInstance();
        mon.add(Calendar.MONTH, -3);
        String startDate = new java.text.SimpleDateFormat("yyyyMMdd").format(mon.getTime());

        // 한글은 url 인코딩을 해준다
        String encodeIdxNm = "";
        try {
            encodeIdxNm = URLEncoder.encode(idxNm, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        // url세팅
        StringBuilder url = new StringBuilder();
        url.append("http://apis.data.go.kr/1160100/service/GetMarketIndexInfoService/getStockMarketIndex");
        url.append("?serviceKey=ZSQ5tFt%2BI3mMbrSETJGSYuuiYkCCg3Djc5AFceQcedwdmP32HOZg3%2B9LFSRkmYMhhpl1YN0eaphylK%2BakSraIg%3D%3D");
        url.append("&numOfRows=100");
        url.append("&resultType=json");
        url.append("&idxNm=" + encodeIdxNm);
        url.append("&beginBasDt=" + startDate);

        JSONObject param = new JSONObject();
        param.put("type", "GET");
        param.put("url", url.toString());

        // 지수정보 API
        JSONObject apiData = Api.callApi(param);

        // 응답 받은 JSON 값중 지수정보 추출
        Object obj = apiData.getJSONObject("response").getJSONObject("body").getJSONObject("items").get("item");

        // 지수정보 배열로 매핑
        ObjectMapper mapper = new ObjectMapper();
        List<StockIndex> result = new ArrayList<StockIndex>();
        try {
            result = Arrays.asList(mapper.readValue(obj.toString(), StockIndex[].class));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        return result;
    }

마무리

회사 업무를 통해 PHP에서는 API를 개발한 경험은 있었다
PHP에서는 cUrl을 통해 통신하였고 JAVA에서는 HttpURLConnection을이용하여 통신하였는데 이 둘은 차이점이 있다고한다.

  1. CURL은 C 라이브러리로 구현되어 있고 HttpURLConnection은 Java에서 제공하는 클래스이다.
  2. CURL은 파일 업로드, 인증, SSL 인증서 검증, HTTP 헤더 제어, 쿠키 관리 등 다양한 기능을 제공한다. 반면에 HttpURLConnection은 단순한 HTTP GET 및 POST 요청 기능만 제공한다.
  3. CURL은 동시에 여러 개의 요청을 처리할 수 있도록 설계되어 있다. 반면에 HttpURLConnection은 동시에 여러 개의 요청을 처리하지 않는다.
  4. CURL은 빠르게 데이터를 가져올 수 있도록 설계되어 있다. 이에 비해 HttpURLConnection은 속도가 느릴 수 있다.
  5. Java의 HttpURLConnection은 예외 처리를 잘 처리하도록 설계되어 있다. 이에 비해 CURL은 예외 처리가 부족할 수 있다.

처음 JAVA를 통한 API개발이라 기대도 되었고 걱정도 되었지만 막상 API를 개발해보니 PHP에서 개발하였을때와 큰차이가 있지는 않았다. URL에 정보를 담아서 보내고 응답을 받아 처리하는 방식은 동일 하였기 때문이다. JAVA언어를 통해 API를 개발하는 경험을 하게 되어 매우 좋은 경험이었다.

0개의 댓글