본문 바로가기
Develop/JSP

공공데이터 API JSP에 적용하기 스타트! (1)

by ys2ys2 2024. 9. 14.

2차 프로젝트 주제 = 공공데이터 API를 이용해서 여행지 추천 + 커뮤니티 사이트 만들기

 

주제를 보자마자 공공데이터 API에 관한 호기심이 막 생겨나고 어떻게 쓸 지 머릿속에서 막 돌아가기 시작했다!

 

그래서 적어보는 공공데이터 API 정복기! (공부용)


아이디어 1.

배너에 이미지 슬라이드 형식으로 해서 이미지들이 슬라이드로 지나가는데

이때 이 이미지들은 전국 축제에 관한 공공데이터를 불러와서 나오게 하고 싶었다!

 

근데 공공데이터중에 친절하게 이미지까지 주는곳은 찾을 수 없었고 그렇다면

내가 그 축제에 맞게 이미지들을 만들어서 매칭해서 나타나게 하면 되지 않을까? 라는 생각으로 진행했다.

 

일단 먼저 공공데이터부터 찾아봤다!

https://www.culture.go.kr/data/openapi/openapiView.do?id=581&category=D&gubun=A

 

문화공공데이터광장-관광 상세

 

www.culture.go.kr

 

문화체육관광부_추천여행지! 이걸로 정해놓고 필요한 값들만 불러오게 할 예정

 


어떻게 해야하는지 구글링해보니까 일단 활용 명세를 보라고 한다!

활용 명세 활용 하기

 

서비스키가 필요한거 같아서 서비스키 발급

서비스키 = 활용신청 후 사용
그렇다면 활용신청!

 

공개된 공공데이터기 때문에 활용신청 하자마자 이메일로 서비스키가 왔다! 바로 넣어서 확인해보기!

 

서비스키 입력

 

Request URL 들어가보니까 잘 나온다

Request URL

 

이제 화면에 한번 짜보려고 한다..

 

요청인자에 필수값은 서비스키밖에 없다.

 

필수 값 확인하기

출력 값도 확인해봤다!

출력 값 확인하기

 

서비스키 넣고 응답에 성공(200) 하면 이런 식으로 나온다.

response 성공시 Example Value

Example Value 보니까

item이라는 배열로 각각의 값들을 전달하고 있었다.

{
  "header": {
    "resultCode": "string",
    "resultMsg": "string"
  },
  "body": {
    "items": {
      "item": [
        {
          "publisher": "string",
          "creator": "string",
          "collectionDb": "string",
          "insertDate": "string",
          "title": "string",
          "description": "string",
          "referenceIdentifier": "string",
          "url": "string",
          "viewCnt": "string",
          "reference": "string",
          "spatialCoverage": "string"
        }
      ]
    },
    "numOfRows": "string",
    "pageNo": "string",
    "totalCount": "string"
  }
}

 

item 배열 안에 어떤 데이터를 어떤 형식으로 나타내주는지 잘 나와있어서 이거대로 하면 될 듯 하다!

 

// 1. 공공데이터 API URL 및 매개변수 설정하기
String apiKey = "제공받은 키 값";
String numOfRows = "7"; // 7개 요청하기

// 2. API 요청 URL 빌드, URL 빌드 및 쿼리 파라미터 구성하기 StringBuilder 사용
// 쿼리 시작은 "?"로 그 후 추가되는 파라미터는 "&"로, ? 뒤에는 key=value 형식
// ex)http://api.example.com?key=value&anotherKey=value2

StringBuilder urlBuilder = new StringBuilder("http://api.kcisa.kr/openapi/API_CNV_061/request");
urlBuilder.append("?" + URLEncoder.encode("serviceKey", "UTF-8") + "=" + URLEncoder.encode(apiKey, "UTF-8")); // API 키 안전하게 인코딩, UTF-8로!
urlBuilder.append("&" + URLEncoder.encode("numOfRows", "UTF-8") + "=" + URLEncoder.encode(numOfRows, "UTF-8")); // 요청 레코드 수(7개 예정) 추가

// 3. HTTP 연결 설정
URL url = new URL(urlBuilder.toString()); // URL 객체 생성, urlBuilder.toString()으로 최종 URL 만들기
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // URL을 통해 연결 객체 생성
conn.setRequestMethod("GET"); // HTTP 요청 방식 설정 (GET)
conn.setRequestProperty("Content-type", "application/json"); // 헤더에 Content-Type 설정하면서 json이라고 정해주기!

// 4. API 응답 처리
int responseCode = conn.getResponseCode(); // 응답 코드 확인해서
System.out.println("Response code: " + responseCode); // 콘솔에 응답 코드 출력하기

// 데이터 받기 위해 읽기 버퍼 생성
BufferedReader rd;
if (responseCode >= 200 && responseCode <= 300) { // 정상 응답이면 
    rd = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));	// 응답 스트림 읽기
} else { // 에러 응답인 경우
    rd = new BufferedReader(new InputStreamReader(conn.getErrorStream(), "UTF-8")); // 에러 스트림 읽기
}
// API 응답 처리
StringBuilder sb = new StringBuilder(); // 응답 내용 담을 StringBuilder
String line;
while ((line = rd.readLine()) != null) { // 버퍼에서 한 줄씩 읽어서 StringBuilder에 추가
    sb.append(line);
}
rd.close(); // 버퍼 닫기
conn.disconnect(); // 연결 종료

// 5. XML 데이터를 문자열로 가져옴
String xmlResponse = sb.toString(); // StringBuilder를 문자열로 변환

// 6. 필요한 데이터 필터링 및 출력
String[] items = xmlResponse.split("<item>"); // 아이템별로 분할
for (int i = 1; i < items.length; i++) { // 첫번째 아이템은 XML 헤더 정보니까 건너뛰고 2번째 아이템부터 처리, for문으로 처리하기
    String item = items[i];	// 개별 아이템 접근

// 7. 각 항목의 필요한 필드 추출
String title = item.split("<title>")[1].split("</title>")[0]; // title
String description = item.split("<description>")[1].split("</description>")[0]; // description
String urlStr = item.split("<url>")[1].split("</url>")[0]; // url
String viewCnt = item.split("<viewCnt>")[1].split("</viewCnt>")[0]; // viewCnt
String spatialCoverage = item.split("<spatialCoverage>")[1].split("</spatialCoverage>")[0]; // spatialCoverage


구글링과 쥐쌤 통해서 만들어봤다! 이제 html 코드에 넣어서 잘 출력되는지 확인해보기!

<div class="item">
            <h2>제목: <%= title %></h2>
            <p>설명: <%= description %></p>
            <p>URL: <a href="<%= urlStr %>"><%= urlStr %></a></p>
            <p>조회수: <%= viewCnt %></p>
            <p>지역: <%= spatialCoverage %></p>
        </div>

결과값

 

잘 나온다!!!!!!

 

앞으로 해야할 거 → 이미지에 대한 정보는 없으니, images 폴더에 각 title에 해당하는 이미지 만들어두고 매칭시키기

그 이미지를 배너에 슬라이드 형식으로 나오게 하고

이미지 클릭시 → 이미지의 title에 연결된 페이지에 해당하는 축제 페이지 만들고 안에 구성을 필요한 공공데이터 api 값들을 받아와서 구성하기!

하면 메인의 배너부분은 끝날 거 같다!