구글 캘린더 API를 자바 기준으로 작성해보겠습니다.
목차
1. 구글캘린더 API 연동
2. Controller구현
3. 화면구현
4. 실행화면
1. 구글캘린더 API 연동
밑에 google API 콘솔로 들어갑니다
https://console.developers.google.com/?hl=ko
프로젝트 만들기 클릭
프로젝트를 만들어줍니다.
라이브러리 -> Calendar API 클릭
사용 설정 클릭
사용자 인증 정보 만들기 클릭
java로 구현하기때문에 웹서버 -> 애플리케이션 데이터 -> 아니요 -> 사용자 인정 정보 클릭
서비스 계정 이름은 아무거나 적고 -> 역할도 적당히 설정 -> 키 유형 JSON 체크 -> 계속
사용자 동의화면을 정해줍니다. -> 저장클릭
사용자 인증 정보 만들기 -> OAuth 클라이언트 ID 클릭
기타유형 -> 생성
접속정보 JSON을 다운 받습니다.
파일명을 변경
client_secret.json
src/main/resources 경로에 넣어줍니다.
dependency
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<!-- google api --> <dependency> <groupId>com.google.api-client</groupId> <artifactId>google-api-client</artifactId> <version>1.22.0</version> </dependency>
<dependency> <groupId>com.google.oauth-client</groupId> <artifactId>google-oauth-client-jetty</artifactId> <version>1.22.0</version> </dependency>
<dependency> <groupId>com.google.apis</groupId> <artifactId>google-api-services-calendar</artifactId> <version>v3-rev235-1.22.0</version> </dependency> |
cs |
java로 접속할 객체를 만들어줍니다.
GoogleCalendarService.java
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
package com.t.hc.beans;
import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Arrays; import java.util.List;
import com.google.api.client.auth.oauth2.Credential; import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp; import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver; import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow; import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets; import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; import com.google.api.client.http.HttpTransport; import com.google.api.client.json.JsonFactory; import com.google.api.client.json.jackson2.JacksonFactory; import com.google.api.client.util.store.FileDataStoreFactory; import com.google.api.services.calendar.Calendar; import com.google.api.services.calendar.CalendarScopes; //import com.google.api.services.calendar.model.CalendarList; //import com.google.api.services.calendar.model.CalendarListEntry;
public class GoogleCalendarService {
private static final String APPLICATION_NAME = "Google Calendar API Java Quickstart";
private static final java.io.File DATA_STORE_DIR = new java.io.File( System.getProperty("user.home"), ".credentials/calendar-java-quickstart");
private static FileDataStoreFactory DATA_STORE_FACTORY;
private static final JsonFactory JSON_FACTORY = JacksonFactory .getDefaultInstance();
private static HttpTransport HTTP_TRANSPORT;
private static final List<String> SCOPES = Arrays .asList(CalendarScopes.CALENDAR);
static { try { HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport(); DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR); } catch (Throwable t) { t.printStackTrace(); System.exit(1); } }
public static Credential authorize() throws IOException { InputStream in = GoogleCalendarService.class .getResourceAsStream("/client_secret.json"); GoogleClientSecrets clientSecrets = GoogleClientSecrets.load( JSON_FACTORY, new InputStreamReader(in));
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder( HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES) .setDataStoreFactory(DATA_STORE_FACTORY) .setAccessType("offline").build(); Credential credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user"); System.out.println("Credentials saved to " + DATA_STORE_DIR.getAbsolutePath()); return credential; }
public static Calendar getCalendarService() throws IOException { Credential credential = authorize(); return new Calendar.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential) .setApplicationName(APPLICATION_NAME).build(); }
// public static void main(String[] args) throws IOException { // com.google.api.services.calendar.Calendar service = getCalendarService(); // // 캘린더 조회 // String pageToken = null; // do { // CalendarList calendarList = service.calendarList().list().setPageToken(pageToken).execute(); // List<CalendarListEntry> items1 = calendarList.getItems(); // // for (CalendarListEntry calendarListEntry : items1) { // System.out.println(calendarListEntry.getSummary()); // System.out.println(calendarListEntry.getId()); // } // pageToken = calendarList.getNextPageToken(); // } while (pageToken != null); // } } |
cs |
접속 테스트를위해 main메소드를 돌려봅니다.
성공적으로 수행되면 최초호출시 권한요청 브라우저 창이 뜸니다.
성공적으로 calendar 목록데이터를 가져온걸 볼수있습니다.
CalendarDto.java 작성
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
package com.t.hc.dto;
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date;
public class CalendarDto {
private String summary; private String startDate; private String startTime; private String endDate; private String endTime; private String description; private String eventId; private String calendarId;
{ description = ""; }
public CalendarDto() {}
public Date getStartDateTime() throws ParseException { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-ddHH:mm"); return format.parse(startDate+startTime); } public Date getEndDateTime() throws ParseException { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-ddHH:mm"); return format.parse(endDate+endTime); }
public String getSummary() { return summary; } public void setSummary(String summary) { this.summary = summary; } public String getStartDate() { return startDate; } public void setStartDate(String startDate) { this.startDate = startDate; } public String getStartTime() { return startTime; } public void setStartTime(String startTime) { this.startTime = startTime; } public String getEndDate() { return endDate; } public void setEndDate(String endDate) { this.endDate = endDate; } public String getEndTime() { return endTime; } public void setEndTime(String endTime) { this.endTime = endTime; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getEventId() { return eventId; } public void setEventId(String eventId) { this.eventId = eventId; } public String getCalendarId() { return calendarId; } public void setCalendarId(String calendarId) { this.calendarId = calendarId; }
@Override public String toString() { return "GoogleCalendarDto [summary=" + summary + ", startDate=" + startDate + ", startTime=" + startTime + ", endDate=" + endDate + ", endTime=" + endTime + ", description=" + description + ", eventId=" + eventId + ", calendarId=" + calendarId + "]"; } } |
cs |
2. Controller구현
캘린더 리스트 Controller 작성
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
package com.t.hc;
import java.io.IOException; import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod;
import com.google.api.services.calendar.Calendar; import com.google.api.services.calendar.model.CalendarList; import com.google.api.services.calendar.model.CalendarListEntry; import com.t.hc.beans.GoogleCalendarService; import com.t.hc.dto.CalendarDto;
@Controller public class HandcodingController {
private Logger logger = LoggerFactory.getLogger(HandcodingController.class);
// 캘린더리스트 @RequestMapping(value="/coding.do", method=RequestMethod.GET) public String coding(Model model) { logger.info("calendarList"); try { Calendar service = GoogleCalendarService.getCalendarService(); CalendarList calendarList = service.calendarList().list().setPageToken(null).execute(); List<CalendarListEntry> items = calendarList.getItems(); model.addAttribute("items", items); } catch (IOException e) { e.printStackTrace(); } return "coding"; }
// 캘린더 생성 처리 @RequestMapping(value="/calendarAdd.do", method=RequestMethod.POST) public String calendarAdd(CalendarDto calDto) { logger.info("calendarAdd "+calDto.toString());
try { Calendar service = GoogleCalendarService.getCalendarService(); com.google.api.services.calendar.model.Calendar calendar = new com.google.api.services.calendar.model.Calendar(); calendar.setSummary(calDto.getSummary()); calendar.setTimeZone("America/Los_Angeles"); service.calendars().insert(calendar).execute(); } catch (IOException e) { e.printStackTrace(); } return "redirect:/coding.do"; }
// 캘린더 삭제 처리 @RequestMapping(value="/calendarRemove.do", method=RequestMethod.POST) public String calendarRemove(HttpServletRequest req) { logger.info("calendarRemove");
String[] chkVal = req.getParameterValues("chkVal"); try { Calendar service = GoogleCalendarService.getCalendarService(); for (String calendarId : chkVal) { service.calendars().delete(calendarId).execute(); } } catch (IOException e) { e.printStackTrace(); } return "redirect:/coding.do"; }
// 캘린더 수정 처리 @RequestMapping(value="/calendarModify.do", method=RequestMethod.POST) public String calendarModify(CalendarDto calDto) { logger.info("calendarModify "+calDto.toString());
try { Calendar service = GoogleCalendarService.getCalendarService(); com.google.api.services.calendar.model.Calendar calendar = service.calendars().get(calDto.getCalendarId()).execute(); calendar.setSummary(calDto.getSummary()); service.calendars().update(calendar.getId(), calendar).execute(); } catch (IOException e) { e.printStackTrace(); } return "redirect:/coding.do"; }
// 캘린더 이동처리 @RequestMapping(value="/schdule.do", method=RequestMethod.GET) public String schdule(Model model, String calendarId, String title) { logger.info("schdule"); model.addAttribute("calendarId", calendarId); model.addAttribute("title", title); return "schdule"; } }
|
cs |
일정이벤트 핸들링할 ajax컨트롤러 작성
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
package com.t.hc;
import java.io.IOException; import java.text.ParseException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController;
import com.google.api.client.util.DateTime; import com.google.api.services.calendar.Calendar; import com.google.api.services.calendar.model.Event; import com.google.api.services.calendar.model.EventDateTime; import com.google.api.services.calendar.model.Events; import com.t.hc.beans.GoogleCalendarService; import com.t.hc.dto.CalendarDto;
@RestController public class CalendarAjaxController {
private Logger logger = LoggerFactory.getLogger(CalendarAjaxController.class);
// 일정 데이터 처리 @RequestMapping(value="/calendarEventList.do", method=RequestMethod.POST) public List<Event> calendarEventList(CalendarDto calDto) { logger.info("calendarEventList "+calDto.toString());
List<Event> items = new ArrayList<Event>(); try { com.google.api.services.calendar.Calendar service = GoogleCalendarService.getCalendarService(); Events events = service.events().list(calDto.getCalendarId()).setOrderBy("startTime").setSingleEvents(true).execute(); items = events.getItems(); } catch (IOException e) { e.printStackTrace(); } return items; }
// 일정 저장 처리 @RequestMapping(value="/calendarEventAdd.do", method=RequestMethod.POST) public Map<String, Boolean> calendarEventAdd(CalendarDto calDto) { logger.info("calendarEventAdd "+calDto.toString());
boolean isc = false; try { Calendar service = GoogleCalendarService.getCalendarService(); Event event = new Event().setSummary(calDto.getSummary()).setDescription(calDto.getDescription()); //시작일 DateTime startDateTime = new DateTime(calDto.getStartDateTime()); EventDateTime start = new EventDateTime().setDateTime(startDateTime).setTimeZone("America/Los_Angeles"); event.setStart(start); //종료일 DateTime endDateTime = new DateTime(calDto.getEndDateTime()); EventDateTime end = new EventDateTime().setDateTime(endDateTime).setTimeZone("America/Los_Angeles"); event.setEnd(end); event = service.events().insert(calDto.getCalendarId(), event).execute(); isc = true; } catch (IOException | ParseException e) { e.printStackTrace(); } Map<String, Boolean> map = new HashMap<String, Boolean>(); map.put("isc", isc); return map; }
// 일정 삭제 @RequestMapping(value="/calendarEventRemoveOne.do", method=RequestMethod.POST) public Map<String, Boolean> calendarEventRemoveOne(CalendarDto calDto) { logger.info("calendarEventRemoveOne "+calDto.toString());
boolean isc = false; try { Calendar service = GoogleCalendarService.getCalendarService(); service.events().delete(calDto.getCalendarId(), calDto.getEventId()).execute(); isc = true; } catch (IOException e) { e.printStackTrace(); } Map<String, Boolean> map = new HashMap<String, Boolean>(); map.put("isc", isc); return map; }
// 일정 수정 @RequestMapping(value="/calendarEventModify.do", method=RequestMethod.POST) public Map<String, Boolean> calendarEventModify(CalendarDto calDto) { logger.info("calendarEventModify "+calDto.toString());
boolean isc = false; try { Calendar service = GoogleCalendarService.getCalendarService(); Event event = service.events().get(calDto.getCalendarId(), calDto.getEventId()).execute(); event.setSummary(calDto.getSummary()).setDescription(calDto.getDescription()); service.events().update(calDto.getCalendarId(), event.getId(), event).execute(); isc = true; } catch (IOException e) { e.printStackTrace(); } Map<String, Boolean> map = new HashMap<String, Boolean>(); map.put("isc", isc); return map; } } |
cs |
3. 화면구현
캘린더 리스트화면
coding.jsp
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>캘린더 관리</title> <script src="./js/jquery-3.1.1.min.js"></script> <script src="./js/bootstrap.min.js"></script> <link rel="stylesheet" href="./css/bootstrap.min.css"> <link rel="stylesheet" href="./css/bootstrap-theme.min.css"> <script type="text/javascript" src='./js/sweetalert.min.js?ver=1'></script> <link rel="stylesheet" type="text/css" href='./css/sweetalert.css?ver=1.2'> <script type="text/javascript" src="./js/calendarList.js"></script> </head> <body> <form action="./calendarRemove.do" method="post" id="frmCalendarRemove"> <table class="table table-bordered"> <tr> <th><input type='checkbox' onclick='checkAllDel(this.checked)' />전체</th> <th>캘린더이름</th> <th>캘린더코드</th> </tr> <c:forEach items="${items}" var="item"> <tr> <td><input type='checkbox' name='chkVal' value="${item.id}" /></td> <td><input type="hidden" name='summarys' value="${item.summary}" /> <a href="./schdule.do?calendarId=${item.id}&title=${item.summary}">${item.summary}</a> </td> <td>${item.id}</td> </tr> </c:forEach> </table> </form> <input type="button" class='btn btn-sm btn-warning' value="캘린더 생성" onclick="calendarAddForm()" /> <input type="button" class='btn btn-sm btn-warning' value="캘린더 수정" onclick="calendarModifyForm()" /> <input type="button" class='btn btn-sm btn-warning' value="캘린더 삭제" onclick="calendarRemove()" /> <!-- 캘린더 생성 modal --> <div class="modal fade" id="calendarAddForm" role="dialog"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal">×</button> <h4 class="modal-title">캘린더 생성</h4> </div> <div class="modal-body"> <!-- 캘린더 생성처리 form --> <form action="./calendarAdd.do" method='post' id='frmCalendarAdd'> <div class='form-group'> <label>캘린더이름</label><input class='form-control' type="text" name='summary' id='summary' /> </div> <div class='modal-footer'> <input type="button" class='btn btn-sm btn-warning' value="확인" onclick="calendarAdd()" /> <input type="reset" class='btn btn-sm btn-warning' value="초기화" /> <input type='button' class='btn btn-sm btn-warning' data-dismiss='modal' value="취소" /> </div> </form> </div> </div> </div> </div> <!-- 캘린더 수정 modal --> <div class="modal fade" id="calendarModifyForm" role="dialog"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal">×</button> <h4 class="modal-title">캘린더 수정</h4> </div> <div class="modal-body"> <!-- 캘린더 생성처리 form --> <form action="./calendarModify.do" method='post' id='frmCalendarModify'> <div class='form-group'> <label>캘린더이름</label><input class='form-control' type="text" name='summary' id='summaryModify' /> </div> <input type="hidden" name="calendarId" id='calendarIdModify' /> <div class='modal-footer'> <input type="button" class='btn btn-sm btn-warning' value="확인" onclick="calendarModify()" /> <input type="reset" class='btn btn-sm btn-warning' value="초기화" /> <input type='button' class='btn btn-sm btn-warning' data-dismiss='modal' value="취소" /> </div> </form> </div> </div> </div> </div> </body> </html> |
cs |
캘린더 일정화면
schdule.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>일정관리</title> <script src="./js/jquery-3.1.1.min.js"></script> <script src="./js/bootstrap.min.js"></script> <link rel="stylesheet" href="./css/bootstrap.min.css"> <link rel="stylesheet" href="./css/bootstrap-theme.min.css"> <script type="text/javascript" src='./js/sweetalert.min.js?ver=1'></script> <link rel="stylesheet" type="text/css" href='./css/sweetalert.css?ver=1.2'> <script type="text/javascript" src="./js/stringBuffer.js"></script> <script type="text/javascript" src="./js/calendar.js"></script> <script type="text/javascript" src="./js/calendarSchdule.js"></script> <style type="text/css"> thead { text-align: center; } thead td { width: 100px; } #tbody td { height: 150px; } #yearMonth { font: bold; font-size: 18px; } </style> </head> <body> <input type="hidden" id="chk" value="0" /> <input type="hidden" id="calendarId" value="${calendarId}" /> <table class="table table-bordered"> <thead id='thead'> <tr> <td colspan="7"> <button type='button' class='btn btn-sm btn-warning' id='moveFastPre' onclick="moveFastMonthPre()">«</button>
<button type='button' class='btn btn-sm btn-warning' id='movePre' onclick="moveMonthPre()">‹</button> <span id='yearMonth'></span> <button type='button' class='btn btn-sm btn-warning' id='moveNext' onclick="moveMonthNext()">›</button> <button type='button' class='btn btn-sm btn-warning' id='moveFastNext' onclick="moveFastMonthNext()">»</button> <div style="text-align: right;"> <span>${title}</span> <input class='btn btn-sm btn-info' type="button" value="주" onclick='tabWeek()' /> <input class='btn btn-sm btn-info' type="button" value="월" onclick='tabMonth()' /> <input class='btn btn-sm btn-info' type="button" value="목록" onclick='location.href="./coding.do"' /> </div> </td> </tr> <tr> <td>일<span class='week'></span></td> <td>월<span class='week'></span></td> <td>화<span class='week'></span></td> <td>수<span class='week'></span></td> <td>목<span class='week'></span></td> <td>금<span class='week'></span></td> <td>토<span class='week'></span></td> </tr> </thead> <tbody id='tbody'></tbody> </table> <!-- 일정 생성 modal --> <div class="modal fade" id="schduleForm" role="dialog"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal">×</button> <h4 class="modal-title">일정등록</h4> </div> <div class="modal-body"> <form class='form-margin40' role='form' action="#" method='post' id='frmSchdule'> <div class='form-group'> <label>제목</label> <input type='text' class='form-control' id='summary' name='summary' placeholder="예: 오후 7시에 멕시코 음식점에서 저녁식사"> </div> <div class='form-group'> <label>시작시간</label> <input class='form-control' type="time" id='startTime' name='startTime'> </div> <div class='form-group'> <label>시작날짜</label> <input class='form-control startDate' type="date" id='startDate' name='startDate' readonly="readonly"> </div> <div class='form-group'> <label>종료시간</label> <input class='form-control' type="time" id='endTime' name='endTime'> </div> <div class='form-group'> <label>종료날짜</label> <input class='form-control startDate' type="date" id='endDate' name='endDate'> </div> <div class='form-group'> <label>내용</label> <textarea rows="7" class='form-control' id="description" name='description'></textarea> </div> <div class='modal-footer'> <input type="button" class='btn btn-sm btn-warning' value="확인" onclick="calendarSchduleAdd()" /> <input type="reset" class='btn btn-sm btn-warning' value="초기화" /> <input type='button' class='btn btn-sm btn-warning' data-dismiss='modal' value="취소" /> </div> </form> </div> </div> </div> </div> <!-- 일정 수정 modal --> <div class="modal fade" id="schduleFormModify" role="dialog"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal">×</button> <h4 class="modal-title">일정수정</h4> </div> <div class="modal-body"> <form class='form-margin40' role='form' action="#" method='post' id='frmSchduleModify'> <div class='form-group'> <label>제목</label> <input type='text' class='form-control' id='modifySummary' name='summary'> </div> <div class='form-group'> <label>내용</label> <textarea rows="7" class='form-control' id="modifyDescription" name='description'></textarea> </div> <input type="hidden" id="modifyEventId" name="eventId" /> <input type="hidden" name="calendarId" value="${calendarId}" /> <div class='modal-footer'> <input type="button" class='btn btn-sm btn-warning' value="확인" onclick="modifyEvent()" /> <input type="reset" class='btn btn-sm btn-warning' value="초기화" /> <input type='button' class='btn btn-sm btn-warning' data-dismiss='modal' value="취소" /> </div> </form> </div> </div> </div> </div> </body> </html> |
cs |
화면 라이브러리는 부트스트랩, jQuery, sweetalert을 씁니다.
기타 util javaScript
stringBuffer.js
1 2 3 4 5 6 7 8 9 10 |
// StringBuffer var StringBuffer = function() { this.buffer = new Array(); }; StringBuffer.prototype.append = function(str) { this.buffer[this.buffer.length] = str; }; StringBuffer.prototype.toString = function() { return this.buffer.join(""); }; |
cs |
달력연산객체를 하나 만들어줍니다.
calendar.js
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
// 캘린더 객체 var calendar = { LEAF : [ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ], //윤년 PLAIN : [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ], //평년 iscLeafCheck : //윤년 판단 function(year) { var isc = false; if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) { // 윤년이면 isc = true; } return isc; }, daysY : //년도에 따른 일수 누적 function(year) { var daySum = 0; for (var i = 1; i < year; i++) { if (this.iscLeafCheck(i)) { daySum += 366; } else { daySum += 365; } } return daySum; }, daysM : //년도누적 + 월 일수 누적 function(year, month) { var daySum = this.daysY(year); for (var i = 1; i < month; i++) { daySum += this.PLAIN[i - 1]; } if (month >= 2 && this.iscLeafCheck(year)) { daySum++; } return daySum; }, daysD : //년도누적 + 월 누적 + 일수 누적 function(year, month, day) { return this.daysM(year, month) + day; }, lastDay : // 구하고자 하는 년월의 최대 일수 function(year, month) { var last_day = 0; if (this.iscLeafCheck(year)) { last_day = this.LEAF[month - 1]; } else { last_day = this.PLAIN[month - 1]; } return last_day; }, isBeforeDays : // 앞의 달에 년도 분기 function(year, month) { var days = 0; if (month == 1) { days = this.lastDay(year - 1, 12); } else { days = this.lastDay(year, month - 1); } return days; }, make : // 해당달력을 배열로 반환 function(year, month) { var dateOfWeek = (this.daysD(year, month, 1)) % 7; var beforeLastDay = this.isBeforeDays(year, month); var startLastDay = beforeLastDay - dateOfWeek + 1; var last_day = this.lastDay(year, month); // 구하고자 하는 년월의 최대 일수 var lastWeekDays = (7 - (dateOfWeek + last_day) % 7) % 7; if (this.iscLeafCheck(year)) { startLastDay++; lastWeekDays++; } var dayArray = new Array(); var cnt = 0; for (var i = startLastDay; i <= beforeLastDay; i++, cnt++) { dayArray[cnt] = i; } for (var i = 1; i <= last_day; i++, cnt++) { dayArray[cnt] = i; } for (var i = 1; i <= lastWeekDays; i++, cnt++) { dayArray[cnt] = i; } return dayArray; }, makeOne : // 달력 한개만 function(year, month){ var last_day = this.lastDay(year, month); // 구하고자 하는 년월의 최대 일수 var dayArray = new Array(); var cnt = 0; for (var i = 1; i <= last_day; i++, cnt++) { dayArray[cnt] = i; } return dayArray; } } |
cs |
캘린더 리스트 화면을 핸들링할 javaScript
calendarList.js
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
// 캘린더 생성폼 호출 function calendarAddForm() { $('#calendarAddForm').modal(); } // 캘린더 생성 처리 function calendarAdd() { var summary = $('#summary').val(); if(summary.trim() == '' || summary.trim().length == 0) { swal('이름','입력해주세요'); return false; } $('#frmCalendarAdd').submit(); } //전체체크 function checkAllDel(bool) { var chkVal = document.getElementsByName("chkVal"); for (var i = 0; i < chkVal.length; i++) { chkVal[i].checked = bool; } } //캘린더 삭제 function calendarRemove() { var chkVal = document.getElementsByName("chkVal"); var n = 0; for (var i = 0; i < chkVal.length; i++) { if(chkVal[i].checked == true){ n++; } } if(n>0){ $('#frmCalendarRemove').submit(); }else { swal("캘린더 삭제", '선택해주세요'); } } // 캘린더 수정 호출 function calendarModifyForm() { var chkVal = document.getElementsByName("chkVal"); var summarys = document.getElementsByName("summarys"); var n = 0; var calendarId = ''; var summary = ''; for (var i = 0; i < chkVal.length; i++) { if(chkVal[i].checked == true){ n++; calendarId = chkVal[i].value; summary = summarys[i].value; } } if(n==1) { $('#frmCalendarModify').find('#summaryModify').val(summary); $('#frmCalendarModify').find('#calendarIdModify').val(calendarId); }else if(n>1) { swal("캘린더 수정", '1개만 선택해주세요'); return false; }else { swal("캘린더 수정", '선택해주세요'); return false; } $('#calendarModifyForm').modal(); } // 캘린더 수정 처리 function calendarModify() { $('#frmCalendarModify').submit(); }
|
cs |
일정을 핸들링할 js
calendarSchdule.js
var data = {} // List<Event> var locationMonth = 0; // 현재 달력위치 var locationYear = 0; // 현재 년도위치 var locationWeek = 0; // 현재 주차위치 // 날짜 테그를 만들어준다 function dayTagFormat(year, month, day) { var tag = new StringBuffer(); tag.append("<td id="+year+month+day+">"); tag.append("<a onclick='schduleAdd("+year+","+month+","+day+")'>"+numFormat(day)+"</a>"); tag.append("</td>"); return tag.toString(); } //숫자 5 -> 05 변경 function numFormat(num) { var str = ''+num; if(num<10 && str.indexOf('0') == -1 || str.length == 1) { str = '0'+num; } return str; } // 시간을 리턴한다 function getTime(item) { return numFormat(item.getHours()) + ":" + numFormat(item.getMinutes()); } // 일정추가 폼 function schduleAdd(year, month, day) { $('.startDate').val(year + "-" + numFormat(month) + "-" + numFormat(day)); $('#summary').val(''); $('#startTime').val(''); $('#endTime').val(''); $('#description').val(''); $('#schduleForm').modal(); } // 유효성 검사 일정 저장처리 function calendarSchduleAdd() { var summary = $('#summary').val(); var startTime = $('#startTime').val().split(":"); var endTime = $('#endTime').val().split(":"); if(summary.trim() == '' || summary.trim().length == 0) { swal('제목','입력해주세요'); return false; }else if($('#startTime').val() == '') { swal('시작시간','입력해주세요'); return false; }else if($('#endTime').val() == '') { swal('종료시간','입력해주세요'); return false; }else if(new Date(0,0,0,endTime[0],endTime[1]).getTime() - new Date(0,0,0,startTime[0],startTime[1]).getTime() < 0) { swal('시간','종료시간이 시작시간보다 늦습니다'); return false; }else if($('#endDate').val() == '') { swal('종료날짜','입력해주세요'); return false; }else if(new Date($('#endDate').val()).getTime() - new Date($('#startDate').val()).getTime() < 0) { swal('날짜','종료일이 시작일보다 늦습니다'); return false; } $("#schduleForm").modal('hide'); swal('calendar', 'google토큰이 필요합니다.'); $.ajax({ url: './calendarEventAdd.do', type: 'post', async: false, data : $('#frmSchdule').serialize(), success: function(msg) { if(msg.isc) { swal('저장', '성공하였습니다'); }else { swal('저장', '실패하였습니다'); } } }); calendarEventList(); screenWriteMonth(); } //달력의 해당 날짜의 요일을 구하기위해 현재위치 반환 function monthDayIndex(month, day) { for(var i=0; i<month.length; i++) { if(month[i]==day) { return i; } } } // 달력 이전으로 이동 function moveMonthPre() { locationMonth--; screenWriteMonth(); } // 달력 다음으로 이동 function moveMonthNext() { locationMonth++; screenWriteMonth(); } // 달력 이전 년도로 이동 function moveFastMonthPre() { locationYear--; screenWriteMonth(); } // 달력 다음 년도로 이동 function moveFastMonthNext() { locationYear++; screenWriteMonth(); } // 화면에 달력과 이벤트를 그려준다 function screenWriteMonth() { var date = new Date(); var month = date.getMonth()+1+locationMonth; if(month == 0) { locationYear--; locationMonth = 12 - Math.abs(locationMonth); month = date.getMonth()+1+locationMonth; }else if(month == 13) { locationYear++; locationMonth = locationMonth - 12; month = date.getMonth()+1+locationMonth; } var months = [month-1, month, month+1]; if(month == 1) { months = [12, month, month+1]; }else if(month == 12) { months = [month-1, month, 1]; } var year = date.getFullYear()+locationYear; var monthDay = calendar.make(year, months[1]); var tag = new StringBuffer(); var startIndex = monthDayIndex(monthDay, 1); var lastIndex = monthDayIndex(calendar.makeOne(year, months[1]), calendar.lastDay(year, months[1])) + startIndex; for(var i=0; i<monthDay.length; i++) { if(i%7 == 0) { tag.append('<tr>'); } if(i<startIndex) { if(months[0]==12) { tag.append(dayTagFormat(year-1, months[0], monthDay[i])); }else { tag.append(dayTagFormat(year, months[0], monthDay[i])); } }else if(i <= lastIndex) { tag.append(dayTagFormat(year, months[1], monthDay[i])); }else { if(months[2]==1) { tag.append(dayTagFormat(year+1, months[2], monthDay[i])); }else { tag.append(dayTagFormat(year, months[2], monthDay[i])); } } if(i%7 == 6) { tag.append('</tr>'); } } $('#tbody').html(tag.toString()); $('#yearMonth').text(year + "년 " + numFormat(months[1]) + "월"); if(data.chk) { for(var i=0; i<data.cnt; i++) { var itemMonth = data.start[i].getMonth()+1; var itemYear = data.start[i].getFullYear(); if((itemMonth == months[1] || itemMonth == months[0] || itemMonth == months[2]) && (itemYear == year || itemYear == year-1 || itemYear == year+1)) { $('#'+itemYear+itemMonth+data.start[i].getDate()).append(eventTagFormat(getTime(data.start[i]), data.title[i], data.eventId[i], data.description[i])); } } } } // 일정 태그를 만들어 준다 function eventTagFormat(time, title, eventId, description) { var tag = new StringBuffer(); tag.append("<p>"); tag.append('<a data-toggle="collapse" data-target="#collapseExample'+eventId+'" aria-expanded="false" aria-controls="collapseExample" onclick="collapse(\''+eventId+'\')">'); tag.append(time+" "+title); tag.append('</a>'); tag.append('<div class="collapse" id="collapseExample'+eventId+'">'); if(description == null) { tag.append('<div class="well">내용이 없습니다</div>'); }else { tag.append('<div class="well">'+description+'</div>'); } tag.append('<div style="text-align: right;"><input type="button" class="btn btn-sm btn-warning" value="수정" onclick="modifyEventModal(\''+title+'\',\''+eventId+'\',\''+description+'\')"/> '); tag.append('<input type="button" class="btn btn-sm btn-warning" value="삭제" onclick="removeEventOne(\''+eventId+'\')"/></div>'); tag.append('</div>'); tag.append("</p>"); return tag.toString(); } // collapse 처리 function collapse(eventId) { $('.collapse').not('#collapseExample'+eventId).each(function(){ $(this).attr('class', 'collapse collapse'); }); } // 일정수정 modal function modifyEventModal(title, eventId, description) { $('#modifySummary').val(title); if(description != 'undefined') { $('#modifyDescription').val(description); }else { $('#modifyDescription').val(''); } $('#modifyEventId').val(eventId); $('#schduleFormModify').modal(); } // 일정수정 처리 function modifyEvent() { var summary = $('#modifySummary').val(); if(summary.trim() == '' || summary.trim().length == 0) { swal('제목','입력해주세요'); return false; } $("#schduleFormModify").modal('hide'); $.ajax({ url: './calendarEventModify.do', type: 'post', async: false, data: $('#frmSchduleModify').serialize(), success: function(msg) { if(msg.isc) { swal('수정', '성공하였습니다'); }else { swal('수정', '실패하였습니다'); } } }); calendarEventList(); if($('#chk').val() == '1') { screenWriteWeek(); }else { screenWriteMonth(); } } // 일정삭제 function removeEventOne(eventId) { $.ajax({ url: './calendarEventRemoveOne.do', type: 'post', async: false, data : { "eventId" : eventId, "calendarId" : $('#calendarId').val() }, success: function(msg) { if(msg.isc) { swal('삭제', '성공하였습니다'); }else { swal('삭제', '실패하였습니다'); } } }); calendarEventList(); if($('#chk').val() == '1') { screenWriteWeek(); }else { screenWriteMonth(); } } // ajax로 이벤트 데이터를 받는다 function calendarEventList() { $.ajax({ url: './calendarEventList.do', type: 'post', data: { "calendarId" : $('#calendarId').val() }, async: false, success: function(lists) { if(lists.length != 0) { data.chk = true; data.cnt = lists.length; data.title = new Array(); data.description = new Array(); data.start = new Array(); data.end = new Array(); data.eventId = new Array(); $.each(lists, function(i, item){ data.title[i] = item.summary; data.description[i] = item.description; data.start[i] = new Date(item.start.dateTime.value); data.end[i] = new Date(item.end.dateTime.value); data.eventId[i] = item.id; }); }else { data.chk = false; } } }); } // 주단위로 화면에 그린다 function screenWriteWeek() { var date = new Date(); var month = date.getMonth()+1+locationMonth; if(month == 0) { locationYear--; locationMonth = 12 - Math.abs(locationMonth); month = date.getMonth()+1+locationMonth; }else if(month == 13) { locationYear++; locationMonth = locationMonth - 12; month = date.getMonth()+1+locationMonth; } var year = date.getFullYear()+locationYear; if(locationWeek < 0) { locationMonth--; month = date.getMonth()+1+locationMonth; if(month == 0) { locationYear--; locationMonth = 12 - Math.abs(locationMonth); month = date.getMonth()+1+locationMonth; year = date.getFullYear()+locationYear; } if(new Date(year, month-1, calendar.lastDay(year, month)).getDay() == 6) { locationWeek = calendar.make(year, month).length/7-1; }else { locationWeek = calendar.make(year, month).length/7-2; } }else if(locationWeek > calendar.make(year, month).length/7-2) { locationMonth++; month = date.getMonth()+1+locationMonth; if(month == 13) { locationYear++; locationMonth = locationMonth - 12; month = date.getMonth()+1+locationMonth; year = date.getFullYear()+locationYear; } locationWeek = 0; } var months = [month-1, month, month+1]; if(month == 1) { months = [12, month, month+1]; }else if(month == 12) { months = [month-1, month, 1]; } var monthDay = calendar.make(year, months[1]); var start = 0+locationWeek*7; var last = 6+locationWeek*7; var startIndex = monthDayIndex(monthDay, 1); var lastIndex = monthDayIndex(calendar.makeOne(year, months[1]), calendar.lastDay(year, months[1])) + startIndex; for(var i=start; i<=last; i++) { if(i<startIndex) { $('.week').eq(i%7).text('('+numFormat(months[0])+'.'+numFormat(monthDay[i])+')'); }else if(i <= lastIndex) { $('.week').eq(i%7).text('('+numFormat(months[1])+'.'+numFormat(monthDay[i])+')'); }else { $('.week').eq(i%7).text('('+numFormat(months[2])+'.'+numFormat(monthDay[i])+')'); } } if(locationWeek != 0) { $('#yearMonth').text(year + "년 " + numFormat(months[1]) + "월 " + numFormat(monthDay[start]) + "일 ~ " + numFormat(months[1]) + "월 " + numFormat(monthDay[last]) + "일"); }else { if(months[1] == 1) { $('#yearMonth').text((year-1) + "년 " + numFormat(months[0]) + "월 " + numFormat(monthDay[start]) + "일 ~ " + year + "년 " + numFormat(months[1]) + "월 " + numFormat(monthDay[last]) + "일"); }else { $('#yearMonth').text(year + "년 " + numFormat(months[0]) + "월 " + numFormat(monthDay[start]) + "일 ~ " + numFormat(months[1]) + "월 " + numFormat(monthDay[last]) + "일"); } } var tag = new StringBuffer(); for(var i=0, j=0, k=0; i<384; i++) { if(i%8 == 0) { tag.append('<tr style="text-align: center;">'); j++; } if(j%2 == 1) { if(i%8 == 0) { tag.append('<td rowspan="2" style="height: 5px;></td>'); tag.append('<td style="height: 5px; border-bottom: 1px dotted orange;">'+numFormat(k++)+':00</td>'); }else { tag.append('<td class="'+j+'" style="height: 5px; border-bottom: 1px dotted orange;"></td>'); } }else { if(i%8 < 7) { tag.append('<td class="'+j+'" style="height: 5px; border-top: 1px dotted orange;"></td>'); } } if(i%8 == 7) { tag.append('</tr>'); } } $('#tbody').html(tag.toString()); // 캘린더 날짜정보 처리 고민필요 지금은 귀찮으니 대충 작성 if(data.chk) { for(var i=start; i<=last; i++) { for(var j=0; j<data.cnt; j++) { if(i<startIndex) { weekStartTimeAppend(i, j, monthDay, months, year, -1); weekEndTimeAppend(i, j, monthDay, months, year, -1); }else if(i <= lastIndex) { if(monthDay[i] == data.start[j].getDate() && months[1] == data.start[j].getMonth()+1 && year == data.start[j].getFullYear()) { if(data.start[j].getMinutes() < 30) { $('.'+(data.start[j].getHours()*2+1)).eq(i%7).html(eventTagFormat(getTime(data.start[j]), data.title[j], data.eventId[j], data.description[j])); }else { $('.'+(data.start[j].getHours()*2+2)).eq(i%7).html(eventTagFormat(getTime(data.start[j]), data.title[j], data.eventId[j], data.description[j])); } } if(data.start[j].getHours() != data.end[j].getHours() || (data.start[j].getMinutes() < 30 && data.end[j].getMinutes() >= 30)) { if(monthDay[i] == data.end[j].getDate() && months[1] == data.end[j].getMonth()+1 && year == data.end[j].getFullYear()) { if(data.end[j].getMinutes() < 30) { $('.'+(data.end[j].getHours()*2+1)).eq(i%7).html(eventTagFormatEnd(getTime(data.end[j]), data.title[j], data.eventId[j], data.description[j])); }else { $('.'+(data.end[j].getHours()*2+2)).eq(i%7).html(eventTagFormatEnd(getTime(data.end[j]), data.title[j], data.eventId[j], data.description[j])); } } } }else { weekStartTimeAppend(i, j, monthDay, months, year, 1); weekEndTimeAppend(i, j, monthDay, months, year, 1); } } } } } // startTime Tag append function weekStartTimeAppend(i, j, monthDay, months, year, num) { if(monthDay[i] == data.start[j].getDate() && months[0] == data.start[j].getMonth()+1) { if(months[0] == 12 && year+num == data.start[j].getFullYear()) { if(data.start[j].getMinutes() < 30) { $('.'+(data.start[j].getHours()*2+1)).eq(i%7).html(eventTagFormat(getTime(data.start[j]), data.title[j], data.eventId[j], data.description[j])); }else { $('.'+(data.start[j].getHours()*2+2)).eq(i%7).html(eventTagFormat(getTime(data.start[j]), data.title[j], data.eventId[j], data.description[j])); } }else if(year == data.start[j].getFullYear()) { if(data.start[j].getMinutes() < 30) { $('.'+(data.start[j].getHours()*2+1)).eq(i%7).html(eventTagFormat(getTime(data.start[j]), data.title[j], data.eventId[j], data.description[j])); }else { $('.'+(data.start[j].getHours()*2+2)).eq(i%7).html(eventTagFormat(getTime(data.start[j]), data.title[j], data.eventId[j], data.description[j])); } } } } // endTime Tag append function weekEndTimeAppend(i, j, monthDay, months, year, num) { if(data.start[j].getHours() != data.end[j].getHours() || (data.start[j].getMinutes() < 30 && data.end[j].getMinutes() >= 30)) { if(monthDay[i] == data.end[j].getDate() && months[2] == data.end[j].getMonth()+1) { if(months[2] == 1 && year+num == data.end[j].getFullYear()) { if(data.end[j].getMinutes() < 30) { $('.'+(data.end[j].getHours()*2+1)).eq(i%7).html(eventTagFormatEnd(getTime(data.end[j]), data.title[j], data.eventId[j], data.description[j])); }else { $('.'+(data.end[j].getHours()*2+2)).eq(i%7).html(eventTagFormatEnd(getTime(data.end[j]), data.title[j], data.eventId[j], data.description[j])); } }else if(year == data.end[j].getFullYear()) { if(data.end[j].getMinutes() < 30) { $('.'+(data.end[j].getHours()*2+1)).eq(i%7).html(eventTagFormatEnd(getTime(data.end[j]), data.title[j], data.eventId[j], data.description[j])); }else { $('.'+(data.end[j].getHours()*2+2)).eq(i%7).html(eventTagFormatEnd(getTime(data.end[j]), data.title[j], data.eventId[j], data.description[j])); } } } } } //일정 종료 태그를 만들어 준다 function eventTagFormatEnd(time, title, eventId, description) { var tag = new StringBuffer(); tag.append("<p>"); tag.append('<a style="color: red;" data-toggle="collapse" data-target="#collapseExample'+eventId+'" aria-expanded="false" aria-controls="collapseExample" onclick="collapse(\''+eventId+'\')">'); tag.append(time+" "+title); tag.append('</a>'); tag.append("</p>"); return tag.toString(); } // 이전 주 이동 function moveWeekPre() { locationWeek--; screenWriteWeek(); } // 다음 주 이동 function moveWeekNext() { locationWeek++; screenWriteWeek(); } //이전 달 주 이동 function moveFastWeekPre() { locationMonth--; screenWriteWeek(); } // 다음 달 주 이동 function moveFastWeekNext() { locationMonth++; screenWriteWeek(); } // 주단위로 바꾼다 function tabWeek() { $('#movePre').attr('onclick', 'moveWeekPre()'); $('#moveNext').attr('onclick', 'moveWeekNext()'); $('#moveFastPre').attr('onclick', 'moveFastWeekPre()'); $('#moveFastNext').attr('onclick', 'moveFastWeekNext()'); if($('#chk').val() != '1') { $('#thead tr:eq(0) td:eq(0)').attr('colspan', '8'); $('#thead tr:eq(1)').prepend('<td>시간</td>'); $('#chk').val('1'); } screenWriteWeek(); } // 월단위로 바꾼다 function tabMonth() { $('#movePre').attr('onclick', 'moveMonthPre()'); $('#moveNext').attr('onclick', 'moveMonthNext()'); $('#moveFastPre').attr('onclick', 'moveFastMonthPre()'); $('#moveFastNext').attr('onclick', 'moveFastMonthNext()'); if($('#chk').val() != '0') { $('#thead tr:eq(0) td:eq(0)').attr('colspan', '7'); $('#thead tr:eq(1) td:eq(0)').remove(); $('.week').text(''); $('#chk').val('0'); } screenWriteMonth(); } $(document).ready(function(){ calendarEventList(); screenWriteMonth(); }); |
cs |
4. 실행화면
캘린더 리스트 화면
캘린더 생성시 modal처리 화면
캘린더 수정시 modal처리 화면
캘린더 삭제시 sweetalert처리 화면
일정 월 처리화면
일정 주 처리화면
일정 상세보기 화면
일정등록 modal처리 화면
일정 수정처리 modal처리 화면
일정 삭제시 sweetalert처리 화면
일정 주 상세보기 화면
이상으로 google calendar API 구현이였는데요
저는 java로 구현했기때문에
만약 배포시 권한동의화면을 띄워야하는데 전혀 써먹지 못합니다.(java코드에서 브라우저를 실행시키기때문에 ㅋㅋ)
소감으로는 API를 쓰는데 생각보다 많은 노력이 필요하고 그 시간에 DB구축하고도 남아돌기 때문에 추천하지 않습니다.
만약 만든다면 배포할때를 위해 javaScript로 구현하시기 바랍니다.
참고 API문서
연동 : https://developers.google.com/google-apps/calendar/quickstart/js
CRUD 코드 : https://developers.google.com/google-apps/calendar/v3/reference/events/get
Data속성 : https://developers.google.com/google-apps/calendar/v3/reference/events
'Programing' 카테고리의 다른 글
그누보드 버전 확인 How to gnuboard CMS version check (0) | 2019.09.18 |
---|---|
php 프로그래밍 게시판 사진 보이게 하는 소스코드 (0) | 2016.03.27 |
알고리즘의 종류 (0) | 2015.10.18 |
br 태그 (0) | 2015.10.18 |
배치파일 명령어 (0) | 2014.03.13 |