안녕하세요. 그린주입니다 ๑'ٮ'๑경험이 많이 부족하지만 최선을 다해 적어보겠습니다!
개요
이번 글에서는 Open API 공휴일 정보 조회 및 DB tb_holiday 저장하기 2편 - 공휴일 정보 조회 방법을 공유하고자 합니다.
## 1편 활용 신청 방법 바로가기
https://green-joo.tistory.com/7
목차
URL & Postman
OpenApiController.java
OpenApiExplorer.java
OpenApiService.java
URL & Postman
발급받은 service Key로 조회가 가능한지 확인하기 가장 쉬운 방법!
api주소 + 기능 이름 + 서비스 키 + 연 + 월을 입력하면 출력 결과를 가져오게 된다.
http://apis.data.go.kr/B090041/openapi/service/SpcdeInfoService/getRestDeInfo?serviceKey=******&solYear=2022&solMonth=01
문제없이 2022년 01월 공휴일이 잘 나오는 것을 볼 수 있습니다.
1편에서 말씀드렸던 제공받은 인증키의 시스템 동기화 프로세스가 되지 않았을 때 결괏값까지 보여드릴게요.
이렇게 가능한지 확인한 뒤에 샘플 코드로 짜보는 것도 좋은 방법이에요!
코드로 실행했을 때 이런 에러가 보인다면 저 같은 신입은 멘붕 올 수도 있을 거 같아요..ㅎㅋㅋㅋ
URL와 Postman 확인은 여기까지!
OpenApiController.java
controller 코드는 아래와 같습니다.
public class OpenApiController {
private final OpenApiService openApiService;
@GetMapping("/holiday")
public ResponseEntity<?> getHolidayController(String solYear, String solMonth) throws IOException { // 공유일 가져오기
return ResponseEntity.ok(openApiService.getHolidayService(solYear, solMonth));
}
}
solYear, solMonth
조회할 연도와 월
OpenApiExplorer.java
공휴일 API에서 제공해준 샘플 코드는 아래와 같습니다.
public class OpenApiExplorer {
public JSONObject getHolidayExplorer(String solYear, String solMonth) throws IOException {
StringBuilder urlBuilder = new StringBuilder("http://apis.data.go.kr/B090041/openapi/service/SpcdeInfoService/getRestDeInfo"); /*URL*/
urlBuilder.append("?" + URLEncoder.encode("serviceKey", "UTF-8") + "=******"); /*Service Key*/
urlBuilder.append("&" + URLEncoder.encode("solYear", "UTF-8") + "=" + URLEncoder.encode(solYear, "UTF-8")); /*연*/
urlBuilder.append("&" + URLEncoder.encode("solMonth", "UTF-8") + "=" + URLEncoder.encode(solMonth, "UTF-8")); /*월*/
URL url = new URL(urlBuilder.toString());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-type", "application/json");
System.out.println("Response code: " + conn.getResponseCode());
BufferedReader rd;
if (conn.getResponseCode() >= 200 && conn.getResponseCode() <= 300) {
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
} else {
rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
}
StringBuilder xmlSb = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
xmlSb.append(line);
}
rd.close();
conn.disconnect();
JSONObject jsonSb = XML.toJSONObject(xmlSb.toString());
return jsonSb;
}
}
getHolidayExplorer 메서드
api로 공휴일 정보를 전달받는 메서드
xml 데이터 포맷을 jsonObject로 변환 후 반환한다.
getHolidayExplorer 코드 순서
- URL과 SeviceKey는 고정되어있고 전달받은 연도, 월을 파라미터로 추가
- String URL을 통해 URL 객체 생성
- url.openConnection() 함수를 통해 connection 생성(웹페이지 URL 연결)
- connection 옵션 설정
ˇ RequestMethod는 요청 방식, RequestProperty 타입 설정(application/json) 형식으로 전송 - conn.getResponseCode() 함수를 통해 요청 전송
ˇ 정상적인 응답은 responseCode = HTTP_OK - Stream 반환 결괏값을 BufferReader를 통해 읽어줍니다.
- 연결 종료
- xml 데이터 포맷인 xmlSb를 jsonObject jsonSb로 변환
- 최종 jsonSb를 반환
OpenApiService.java
service 코드는 아래와 같습니다.
public class OpenApiService {
private final OpenApiExplorer openApiExplorer;
@Transactional
public List<HolidayResponseDto> getHolidayService(String solYear, String solMonth) throws IOException { // 공휴일 가져오기
// 샘플코드를 활용해서 xml -> jsonObject로 변환
List<HolidayResponseDto> result = new ArrayList<>();
JSONObject jsonData = openApiExplorer.getHolidayExplorer(solYear, solMonth);
JSONObject body = jsonData.getJSONObject("response").getJSONObject("body");
if (body.getInt("totalCount") != 0) {
// 공휴일 값이 하나일 때는 item이 jsonObject로 받아지기 때문에 조건문 사용
if (body.getInt("totalCount") == 1) {
HolidayResponseDto responseDto = new HolidayResponseDto();
JSONObject item = body.getJSONObject("items").getJSONObject("item");
if (item.getString("isHoliday").equals("Y")) { // 공휴일이 맞을 경우
String holidayDate = String.valueOf(item.getInt("locdate"));
String holidayName = item.getString("dateName");
responseDto.setHolidayDate(holidayDate);
responseDto.setHolidayName(holidayName);
result.add(responseDto);
}
} else {
JSONArray items = body.getJSONObject("items").getJSONArray("item");
for (Object item : items) { // 해당 월 공휴일 갯수
HolidayResponseDto responseDto = new HolidayResponseDto();
JSONObject map = new JSONObject(new Gson().toJson(item)).getJSONObject("map");
if (map.getString("isHoliday").equals("Y")) { // 공휴일이 맞을 경우
String holidayDate = String.valueOf(map.getInt("locdate"));
String holidayName = map.getString("dateName");
responseDto.setHolidayDate(holidayDate);
responseDto.setHolidayName(holidayName);
result.add(responseDto);
}
}
}
}
return result;
}
}
getHolidayService 메서드
getHolidayExplorer에서 받아온 JsonObject jsonDate 안에 데이터를 Dto로 변환하고 반환하는 메서드
getHolidayService 코드 순서
- getHolidayExplorer에서 받은 jsonObject에서 body에 해당하는 부분을 가져옵니다.
ˇ body 안에는 페이지당 항목수 / 페이지 / 모든 항목수 / 아이템(날짜/순번/종류/휴일 여부/명칭) - 항목수에 따라 item의 타입이 다르기 때문에 totalCount(모든 항목수)를 확인하여 타입 생성
ˇ 1개일 경우 item(jsonObject), 2개 이상일 경우 item(jsonArray) - 휴일 여부 확인 후 날짜(Int), 명칭(String) 데이터 추출
ˇ 공휴일로 조회할 경우 휴일이 무조건 "Y"인지 활용 가이드에 설명이 없어 넣어두었습니다. - 추출한 데이터를 Dto에 set 한 뒤 List에 add 합니다.
- 최종 result를 반환
[ Api Test ]
test 실행
// 공휴일이 없을 경우
[]
// 1개 이상일 경우
[
{
"holidayDate": "20220101",
"holidayName": "1월1일"
},
{
"holidayDate": "20220131",
"holidayName": "설날"
}
]
성공!!
마무리
이렇게 Open API 공휴일 정보 조회 및 DB tb_holiday 저장하기 2편 - 공휴일 정보 조회 방법에 대해 알아보았습니다. 다들 성공하셨을까요??
- 3편은 "DB tb_holiday에 저장하기"입니다!
https://green-joo.tistory.com/9
긴 글 봐주셔서 감사합니다!
오늘도 행복한 하루 보내세요 ✿'◡'✿