Tác giả: Phạm Huy Hoàng
Mục đích: Chủ đề bài viết này để xây dựng 1 ứng dụng quản lý lịch, thời gian biểu tương tự như Google Calendar, sau đó đồng bộ lịch của ứng dụng với lịch của Google Calendar thông qua Google API.
Bài viết được chia làm 3 phần:
· Phần 1: Xây dựng ứng dụng quản lý lịch + thời gian biểu đơn giản.
· Phần 2: Tìm hiểu về Google Calendar API. Hướng dẫn viết bộ wrapper Java để gọi Restful API.
· Phần 3: Tích hợp bộ wrapper vào ứng dụng, thực hiện sync ứng dụng và Google Calendar.
Yêu cầu về kiến thức cơ bản:
- · Nắm vững khái niệm về ngôn ngữ lập trình Java, lập trình thao tác hướng đối tượng
- · Nắm vững khái niệm về lập trình web sử dụng J2EE hay JavaEE với các kiến thức về Servlet, JSP
- · Nắm vững khái niệm về cơ chế Filter và RequestDispatcher trong Servlet
- · Nắm vững khái niệm về Hibernate và cách cài đặt Hibernate (vui lòng xem lại bài Hibernate kết hợp với SQLServer)
Yêu cầu phần mềm:
· JDK 6 update 22
· NetBean IDE 6.9.1
· Server: Apache Tomcat 6.0.26
· DBMS: SQL Server 2008 Express
Phần 1: Xây dựng ứng dụng quản lý lịch + thời gian biểu đơn giản
Vì phần này không có khái niệm gì mới nên chúng ta bắt tay vào làm demo luôn.
Database:
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Khóa chính của các bảng đều là Auto Identitfy.
Các giá trị CalendarGoogleID và EventGoogleID được lưu trữ để hỗ trợ cho việc đồng bộ với Google Calendar sau này.
Lưu ý: đa số nội dung diễn giải bên dưới code chụp hình sẽ hướng tới diễn tả trọng tâm quan trọng trong code (sẽ có các đường vẽ đỏ hay các đánh dấu đó), các nội dung đơn giản về mức độ cơ bản chúng tôi xin phép không giảng giải.
Chúng ta tạo 1 web app mới.
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Set các giá trị của file Hibernate.cfg.xml
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Tạo file hibernate.url
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Tạo Hibernate Mapping File và POJO
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Vì các bảng của chúng ta có khóa là auto identitty, cần sửa lại 1 chút để Hibernate tạo đúng câu lệnh SQL
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Sửa tương tự cho file AppEvent.
Cấu trúc Project hiện tại
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Chúng ta bắt đầu viết 1 số hàm trong class DAO, hỗ trợ công việc kết nối database
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Các hàm DAO đã đầy đủ. Cấu trúc project hiện tại:
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Chúng ta bắt đầu tạo trang Login và đăng ký cho người dùng. Đầu tiên, chúng ta tạo AccountServlet
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Ta tạo trang login.jsp và register.jsp. Quí vị tạo sẵn trang index.jsp mặc định.
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Code trong AccountServlet
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Đoạn gạch đỏ thứ nhất: Chúng ta lấy tất cả Calendar của người dùng, đưa vào request để show trong trang index.
Đoạn thứ 2: Sử dụng Hibernate để add user vào database.
Clean & Build. Deploy chương trình, chúng ta nhận được kết quả:
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Bấm nút Register
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Bấm nút Log in.
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
(Nếu chưa tạo trang index.jsp sẽ không hiện ra trang này).
Bắt đầu code để hiện thị danh sách lịch của user trong trang index.jsp. Quí vị vui lòng add thêm taglib (phần đánh dấu đỏ). Taglib fn là taglib hỗ trợ tìm số phần tử của 1 list
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Trong trang index, có form để người dùng thêm calendar mới
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Ta tạo thêm CalendarServlet
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Sau khi add, load ngược lại từ database lên, đưa vào request. Quí vị tạo sẵn file calendarDetail.jsp, chứa thông tin chi tiết của 1 calendar.
Deploy & Run, ta có:
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Bấm Add
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Bấm Detail
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Ta tiếp tục code file calendarDetail.jsp
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Form add event
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Ta tạo tiếp Servlet cuối cùng: EventServlet
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Để đơn giản hóa bản demo, ta tạm cho người dùng nhập ngày tháng theo mẫu, sau đó parse bằng SimpleDateFormat. Việc validate v…v xin nhường lại cho quý vị tự tìm hiểu.
Deploy & Run, chúng ta có.
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Bấm Add
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
=====================================================================
Ứng dụng của chúng ta tạm thời đã xong. Tuy nhiên quí vị nên tiếp tục làm theo hướng dẫn sau để tăng tính usability của ứng dụng
Bước 1: Sử dụng Bootstrap DateTimePicker để hỗ trợ việc chọn thời gian
Quý vị sẽ cần những tool sau đây:
Bootstrap 2.3.2: Tải tại http://getbootstrap.com/2.3.2/
Jquery 1.10.2: Tải tại http://jquery.com/download/
Bootstrap DateTime picker: http://tarruda.github.io/bootstrap-datetimepicker/
Để tiện sử dụng, quý vị có thể tải bộ tích hợp cả 3 tool trên trong link dưới đây:
Sau khi tải về, quý vị giải nén file bootstrap_pack.rar
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Bỏ thư mục bootstrap vào thư mục Web Pages của ứng dụng
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Tiếp theo, ta add file css, javascript vào file calendarDetail.jsp
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Thay 2 ô textbox chọn ngày tháng như sau, lưu ý giá trị name của 2 input vẫn phải là startTime và endTime
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Chạy script để init datepicker
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Dấu # để chọn id của div timepicker. Jquery là 1 thư viện javascript rất mạnh và phổ biến. Quý vị có thể tìm hiểu thêm về jquery tại: http://jquery.com/
Tận hưởng thành quả:
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Bấm Add.
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Bước 2: Sử dụng fullCalendar và ajax để hiện thị event.
Ở bước này, chúng ta sẽ sử dụng thư viện fullCalendar để hiện thị event dưới dạng lịch.
Quý vị tải fulCalendar bản 1.6.4 tại: http://arshaw.com/fullcalendar/download/
Quý vị giản nén file fullcalendar-1.6.4.zip, vào thư mục full calendar, bỏ 2 file fullcalendar.css và fullcalendar.js vào thư mục bootstrap
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Tiếp tục add css và js vào file calendarDetail.jsp
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Chúng ta test thử calendar được tạo ra
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Nội dung gạch chéo trong phần code trên, quí vị nhớ xóa bỏ đi.
Kết quả:
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
FulCalendar có thể load event dưới dạng json. Quý vị tải thư viện gson bản 2-2-4 trong link dưới đây
http://code.google.com/p/google-gson/downloads/list
Giản nén file google-gson-2.2.4-release, ta add file gson-2.2.4.jar vào library.
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Tạo class EventJson với các trường sau. Các event của class này sẽ được serialize thành chuỗi json, hỗ trợ hiển thị event:
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Ta bổ sung thêm phần GetEvent trong EventServlet
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Test thử hàm này, ta được chuỗi Json như sau:
http://localhost:8084/CalendarManager/EventServlet?action=GetEvents&calendarID=3
[
{
"id": "8",
"title": "10:00 - 12:00: Go Learn",
"start": "2013-10-22 10:00",
"end": "2013-10-23 12:00"
},
{
"id": "4",
"title": "07:00 - 14:00: Do something else",
"start": "2013-10-10 07:00",
"end": "2013-10-10 14:00"
},
{
"id": "3",
"title": "16:00 - 17:00: Go Play",
"start": "2013-10-20 16:00",
"end": "2013-10-20 17:00"
},
{
"id": "2",
"title": "09:00 - 10:00: Go Eat",
"start": "2013-10-20 09:00",
"end": "2013-10-20 10:00"
}
]
Tiếp theo, ta set event source lại cho calendar trong calendarDetail.jsp
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
HTML source và thành quả
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Ứng dụng đã cho phép tạo event mới, tuy nhiên, chúng ta chưa làm chức năng sửa thông tin và xóa event. Tiếp tục thực hiện các bước sau:
Bước 1: Sửa constructor của class EventJson
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Bước 2: Sửa lại EventServlet, bổ sung thêm action
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Bước cuối cùng: Tạo file eventDetail.jsp
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Taglib fmt để format ngày tháng.
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Để ý kĩ phần pattern trong tag fmt
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Giá trị calendarID hidden để hỗ trợ redirect. Sở dĩ ta có thể lấy thẳng calendarID và hibernate đã hỗ trợ mapping giữa object AppCalendar và AppEvent.
Clean & Build, ta được
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Click vào 1 event
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Sửa thông tin, bấm update
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Kết quả
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Khi muốn delete, bấm vào event.
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Nhấn Delete
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Chúc mừng quý vị vừa hoàn thành xong phần 1 của tutorial, tạo 1 app đơn giản để quản lý lịch và thời gian biểu.
Ở bài viết sau, chúng tôi sẽ giới thiệu về 1 số khái niệm và cơ chế hoạt động của GoogleAPI, cùng với hướng dẫn viết 1 bộ wrapper để gọi API này. Mong quí vị đón xem.
Bình luận (0)
Add Comment