일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 자동빌드
- java
- spring
- mssql
- stream api
- poi
- ci/cd
- MessageQueue
- jqGrid
- 보안
- DevOps
- 대용량 업로드
- docker
- 제이쿼리그리드
- JQuery
- Javascript
- apache.poi
- QueryDSL
- 자바8
- Stream
- sqlserver
- 엑셀 업로드
- Jenkins
- 스트림
- 그리드
- mom
- ORM
- 자동배포
- JPA
- rabbitmq
- Today
- Total
개발 메모장
[Java] 공공데이터 - 공휴일 API 사용하기 본문
#. 웹에서 15일, 30일을 선택하여 데이터를 처리하는 로직을 만들어야 했었습니다.
#. 15일과 30일이 주말 또는 공휴일인 경우 그 전의 평일을 웹에 보여줘야 했습니다.
#. 주말의 경우엔 일반적으로 처리가 가능하나 공휴일은 그렇지 않기에 정부에서 제공하는 공휴일 API를 사용하기로 했습니다.
- Step 1. 현재 년과 월, 15일 및 30일에 대한 변수 생성
- ModelAndView를 이용해 JSP로 데이터를 리턴해 웹에 뿌려줄 것입니다.
- Java에서 기본적으로 제공하는 라이브러리인 Util > Calendar 메서드를 이용해 년, 월을 가져옵니다.
public ModelAndView availableDay(Map<String, Obejct> param, ModelMap modelMap) {
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH)+1;
int halfDay = 15;
int endDay = 30;
return new ModelAndView("JSP 경로");
}
- Step 2. 날짜 체크하는 메서드 생성 및 로직 구성
- 생성한 변수를 파라미터로 넘겨 처리하는 메서드 생성 및 로직을 구성할 것입니다.
- 로직에는 공휴일 및 주말을 체크해야 하는 내용이 필요하며 getDayCheck 메서드에서 처리할 예정입니다.
- 위 로직에서 추가한 로직부터 작성합니다.
public ModelAndView availableDay(Map<String, Obejct> param, ModelMap modelMap) {
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH)+1;
int halfDay = 15;
int endDay = 30;
halfDay = getDayCheck(year, mmonth, halfDay);
endDay = getDayCheck(year, mmonth, endDay);
modelMap.put("halfDay", String.format("04d-%02d-%02d", year, month, halfDay));
modelMap.put("endDay", String.format("04d-%02d-%02d", year, month, endDay));
return new ModelAndView("JSP 경로");
}
- 전달받은 파라미터로 Calendar 메서드에 날짜를 세팅해 줍니다.
public static int getDayCheck(int year, int month, int day) throws IOException {
Calendar cal = Calendar.getInstance();
cal.set(year, month, day);
List<Integer> holidays = getHolidays(year, month);
// 체크 로직은 아래에서 추가 예정
return cal.get(Calendar.DAY_OF_MONTH);
}
- Step 3. 주말 및 공휴일에 대한 유효성 검사를 한 번에 하기 위해 공휴일 체크 메서드 생성
- 공휴일의 경우 해당 년, 월 파라미터를 입력 시 그에 대한 공휴일의 날짜를 리턴해옵니다.
- getHolidays라는 메서드를 생성해 로직을 구성합니다.
- API 사용을 위한 준비사항
1. 공공데이터포털 회원가입
2. 사용하려는 API의 KEY 발급
3. API 사용방법 인지(공휴일 API는 리턴 값이 XML 형식으로 오기 때문에 편한 사용을 위해 json 파싱처리함)
- API 사용방법은 아래 참조에 기재한 사이트를 확인 바랍니다.
public static List<Integer> getHolidays(int year, int month) throws IOException {
String apiUrl = "공휴일API의 url" // 웹사이트 내 참고문서 확인
String apiKey = "API 이용을 위한 일반 인증키"
// 요청 URI 작성(예를 위해 작성한 것이므로 참고문서 확인 후 넣기)
String requestUrl = "키=" + apiKey
+ "년=" + String.format("%04d", year)
+ "월=" + String.foramt("%02d", month);
// API 통신을 위한 세팅
URL url = new URL(apiUrl + requestUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-type", "application/json");
BufferedReader rd;
if(conn.getResponseCode() >= 200 && conn.getResponseCode() < 300) {
// 정상처리 시
rd = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
} else {
// 에러발생 시
rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
}
// 받은 데이터 담기
StringBuilder sb = new StringBuilder();
String line;
while((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
conn.disconnect();
// 받은 데이터가 XML형식이므로 json 형태로 파싱
List<Integer> result = new ArrayList<Integer>();
JSONObject json = XML.toJSONObject(sb.toString());
String jsonStr = json.toString();
// 사용할 데이터 찾아 변수에 담기
json = (JSONObject) json.get("depth 1");
json = (JSONObject) json.get("depth 2");
if(!(json.get("depth 3") instanceof JSONObject)) {
// 에러 처리
}
json = (JSONObject) json.get("depth 3");
Object item = json.get("depth 4");
// list에 담기(여러 개 일 때 처리방법)
if(item instanceof JSONArray) {
JSONArray items = (JSONArray) item;
for(int i = 0; i < items.length(); i++) {
json = (JSONObject) items.get(i);
// 키에 대한 값은 yyyyMMdd로 가져오므로
// 날짜가 필요한 상황에선 100으로 나눈 나머지가 날짜가 될 것
result.add(json.getInt("날짜키") % 100);
}
// list에 담기(한 개 일 때 처리방법)
} else if(item instanceof JSONObject) {
json = (JSONObject) item;
result.add(json.getInt("날짜키") % 100);
}
return result;
}
- Step 4. 날짜를 토, 일요일, 공휴일인지 체크
- 15, 30이라는 값이 holidays에 포함되는지 확인하기 위한 로직을 추가합니다.
- Step 2에서 만든 메서드의 나머지 부분을 채울 것입니다.
public static int getDayCheck(int year, int month, int day) throws IOException {
Calendar cal = Calendar.getInstance();
cal.set(year, month, day);
List<Integer> holidays = getHolidays(year, month);
while(cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY ||
cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY ||
holidays.contains(cal.get(Calendar.DAY_OF_MONTH))) {
// while문에 걸릴 시 토, 일, 공휴일이기 때문에 날짜를 전날 만듦
cal.add(Calendar.DATE, -1);
}
return cal.get(Calendar.DAY_OF_MONTH);
}
#. 위와 같이 처리해 주면 토요일, 일요일, 공휴일을 제외한 이전 평일의 날짜를 가져올 수 있게 됩니다.
#. 이를 원하는데로 가공하여 사용하면 될 것입니다.
#. 참고로 2월의 경우엔 날짜가 다르므로 이에 대한 처리는 Step 1. 에서 추가 처리해 주면 될 듯합니다.
if(month == Calendar.FEBUARY) {
if(윤달 체크) {
endDay = 28;
} else {
endDay = 29;
}
}
#. 자주 사용해야 하는 경우 API 통신을 계속 해야므로 이보다는 몇 년치 데이터를 DB에 저장하여 호출해 사용하는 것이 좋습니다.
#. 게다가 가끔 공공데이터에서 오류를 뱉는 경우도 있기 때문에 DB 저장이 더 낫다고 볼 수 있습니다.
===========================================================
틀린 내용이 있거나 이견 있으시면 언제든 가감 없이 말씀 부탁드립니다!
참조 : https://www.data.go.kr/data/15012690/openapi.do
===========================================================
'Java' 카테고리의 다른 글
[Java] Stream API(1) - 스트림 데이터 생성 (0) | 2023.12.12 |
---|---|
[Java] Zip 파일 생성 후 파일 다운로드(Ajax 이용) (1) | 2023.12.08 |
[Java] OOM과 GC (Out of Memory Error와 가비지 컬렉터) (1) | 2023.12.04 |
[Java] String, StringBuffer, StringBuilder의 특징 및 차이점 (1) | 2023.11.29 |
[Java] try with Resources 문(리소스 자동 반환) (2) | 2023.11.27 |