Weitere ähnliche Inhalte Ähnlich wie Google App Engine Using Eclipse (20) Mehr von Software Park Thailand (20) Google App Engine Using Eclipse1. 1
Hand-on
Exercises
การพัฒนาโปรแกรม
Web Programming
บน Cloud Computing
โดยใช้
Google App Engine
Assoc. Prof. Dr.Thanachart Numnonda
and
Asst Prof.Thanisa Kruawaisayawan
Mini Master of Java Technology
Faculty of Information Technology
King Mongkut Institute of Technology Ladkrabang
August 2011
Thanachart Numnonda / Thanisa Kruawaisayawan
3. 3
บทนำ
เอกสารนี้ใช้ในการประกอบการสอนวิชา Java 301 : EJB 3.0 and Google App Engines ของ
หลักสูตร Mini Master of Java Technology คณะเทคโนโลยีสารสนเทศ สถาบันพระจอมเกล้าเจ้าคุณทหาร
ลาดกระบัง โดยมีจุดประสงค์เพื่อให้ผู้เรียนได้เข้าใจถึงการพัฒนาโปรแกรม Web Application บน Cloud
Computing ที่รับโดยใช้ infrastructure ของ Google โดยใช้ Java Servlet/JSP และ Google App Engine API
ทั้งนี้แบบฝึกหัดนี้อ้างอิงกับเครื่องมือพัฒนาโปรแกรมจาวา Eclipse 3.6
thananum@gmail.com
twitter.com/thanachart
www.facebook.com/thanachart
www.thaijavadev.com
สิงหาคม 2554
Thanachart Numnonda / Thanisa Kruawaisayawan
4. 4
สารบัญ
Exercise 1 การพัฒนาโปรแกรมเว็บโดยใช้ Google App Engine.............................................................. 4
Exercise 2 การใช้ Mail API และ URLFetch บน GAE....................................................................... 16
Exercise 3 การใช้ Datastore ของ Google App Engine โดยใช้ Java Persistence API (JPA).................22
Exercise 4 การพัฒนาโปรแกรมโดยใช้ Google Web Toolkit Framework.............................................34
Exercise 5 GWT : Client/Server Communication........................................................................... 42
Exercise 6 การพัฒนาโปรแกรม RIA ที่เรียกใช้ Web Services............................................................... 46
Thanachart Numnonda / Thanisa Kruawaisayawan
5. 5
Exercise 1 การพัฒนาโปรแกรมเว็บโดยใช้ Google App Engine
แบบฝึกหัดนี้เป็นการพัฒนาโปรแกรม Web Application โดยจะติดตั้งและรันโปรแกรมอยู่บน Google
App Engine ซึ่งใช้ Infrastructure ของ Google ในการรันโปรแกรม Google App Engine จัดเป็น Cloud
Computing ประเภท Platform as a Service (PaaS) ทำให้นักพัฒนาการโปรแกรมสามารถที่จะติดตั้งโปรแกรม
บนแพลตฟอร์มที่ทาง Google จัดเตรียมไว้ให้ โดยในปัจจุบันได้กำหนด API ไว้สองภาษาคือ Java และ Python
แบบฝึกหัดนี้จะใช้ Eclipse เวอร์ชั่น 3.6 ในการพัฒนาโปรแกรมสำหรับ Google App Engine และใช้
Google App Engine Plugin Module มาช่วยในการพัฒนาโปรแกรม
1.1 การติดตั้งและเริ่มต้นการใช้งาน Google App Engine
Google App Engine เป็นแพลตฟอร์มที่ให้นักพัฒนาโปรแกรมสามารถรันโปรแกรมเว็บแอปพลิเคชั่น
บน Google's Infrastructure ได้ โดยนักพัฒนาจะต้องมี account ของ Google และจะต้องติดตั้ง Google App
Engine SDK ซึ่งรายละเอียดการใช้งาน Google App Engine สามารถดูได้ที่
http://code.google.com/appengine/ โดยเราสามารถที่จะสรุปขั้นตอนการติดตั้งโปรแกรม NetBeans เพื่อ
พัฒนา Google App Engine ได้ดังนี้
1. ทำการลงทะเบียน App Engine Account โดยใช้ Google Account ที่
http://code.google.com/appengine/
2. ทำการติดตั้งโปรแกรม Eclipse version 3.6
3. รันโปรแกรม Eclipse แล้วเลือกเมนู Help > Install New Software
4. ในไดอะล็อก install กำหนดค่าในฟิลด์ work with เป็น http://dl.google.com/eclipse/plugin/3.6 แล้ว
กดปุ่ม Add
5. เมื่อไดอะล็อก Add Repository ให้กดปุ่ม OK (ไม่ต้องใส่ค่า Name)
6. เลือกรายการทั้งสามดังรูป แล้วกดปุ่ม Next
การพัฒนาโปรแกรมเว็บโดยใช้ Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan
6. 6
รูปที่ 1.1 รายการ Available Softwares
7. โปรแกรมจะประเมินซอฟต์แวร์ต่างๆที่จะต้องติดตั้ง แล้วจะแสดงผลออกมาดังรูป แล้วให้กดปุ่ม Next
รูปที่ 1.2 รายละเอียดการติดตั้ง
การพัฒนาโปรแกรมเว็บโดยใช้ Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan
7. 7
8. เลือกช่องยอมรับ License Agreement แล้วกดปุ่ม Finish โปรแกรมจะทำการติดตั้ง Plugin จนสำเร็จ
1.2 การทดสอบ Sample GuestBook Project
ขั้นตอนนี้จะเป็นการสร้าง Sample Project ที่มีอยู่แล้วเพื่อทดลองรันบน Development Server ซึ่งมีขั้น
ตอนดังนี้
1. เลือกเมนู File => New => Other
2. ในไดอะล็อก New ให้เลือก Categories เป็น Google > Web Application Project และเลือก
Projects เป็น Guest Book และกำหนด Package เป็น Test แล้วกด Finish
3. คลิ๊กขวาที่โหนด guestbook แล้วเลือกคำสั่ง Run > Web Application จะเห็นผลลัพธ์ของโปรแกรมดัง
ตัวอย่างในรูป
รูปที่ 1.3 ตัวอย่างผลลัพธ์การรันโปรแกรม guestbook
1.3 การติดตั้ง Sample GuestBook Project บน Google App Engine
ขั้นตอนนี้จะเป็นการติดตั้ง Sample Project ลงบน Google App Engine ซึ่งมีขั้นตอนดังนี้
การพัฒนาโปรแกรมเว็บโดยใช้ Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan
8. 8
1. เราสามารถที่จะทำการ Deploy โปรเจ็คนี้ลงบน Google App Engine โดยการไป sign up เข้า account
ของเราที่ Google App Engine ที่ https://appengine.google.com/ แล้วกดปุ่ม Create an
Application
2. กำหนดค่า Application Identifier: เป็น thaijavaapp และ Application Title: เป็น Thai Java
Google App ดังรูปที่ 1.4 แล้วกดปุ่ม Save
รูปที่ 1.4 การสร้าง Application สำหรับ Google App Engine
3. Google App Engine จะแสดงรายชื่อ Application ใหม่ที่กำหนดขึ้นดังรูปที่ 1.5
รูปที่ 1.5 การแสดงรายการ My Applications ใน Google App Engine
การพัฒนาโปรแกรมเว็บโดยใช้ Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan
9. 9
4. ทำการติดตั้งโปรเจ็คบน Google App Engine คลิ๊กขวาที่โหนด GuestBook แล้วเลือก Google >
Deploy to App Engine
5. ไดอะล็อก Deploy Project to Google App Engine จะแสดงขึ้นดังรูป แล้วกด App Engine Project
Setting
6. ในไดอะล็อก Properties for GuestBook ให้กำหนด Application ID เป็น thaijavaapp และ Version
เป็น 1 ดังรูป แล้วกด OK
7. ในไดอะล็อก Deploy Project to Google App Engine กดปุ่ม Deploy
8. ทดสอบโปรแกรมที่ติดตั้งโดยรันที่ url ที่ชื่อ http://thaijavaapp.appspot.com/GuestBook
การพัฒนาโปรแกรมเว็บโดยใช้ Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan
10. 10
1.4 การสร้าง Web Application Project
ขั้นตอนนี้จะเป็นการพัฒนาโปรแกรม Web Application เพื่อทดลองติดตั้งลง Google's
Infrastructure โดยการสร้าง Project ใหม่ขึ้นมาใน ซึ่งมีขั้นตอนดังนี้
1. เลือกเมนู File => New => Web Application Project..
2. กำหนด Project Name เป็น thaijavaapp กำหนด Package: เป็น com.thaijavadev.timerproject
และไม่เลือกช่อง Use Google Web Toolkit ดังรูป แลัวกด Finish
3. เลือกหน้าต่าง Projects แล้วคลิ๊กขวาที่โหนด thaijavaapp
4. ในไดอะล็อก New > Java Class กำหนด Name เป็น TimerServlet และ Package เป็น
com.thaijavadev.timerproject แล้วกด Finish
5. ปรับปรุงโปรแกรม TimerServlet.java ให้เป็นไปดัง Listing ที่ 1.1
การพัฒนาโปรแกรมเว็บโดยใช้ Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan
11. 11
6. เพิ่ม tag <servlet> ในไฟล์ web.xml ดัง Listing ที่ 1.2
7. ทำการรันโปรแกรมเพื่อทดสอบบน localhost แล้วทำการ deploy บน Google App Engine แล้วทดลอง
รันโปรแกรมที่ http://thaijavaapp.appspot.com/TimerServlet จะได้ผลลัพธ์ดังรูปที่ 1.6
รูปที่ 1.6 ผลลัพธ์การัรนโปรแกรม TimerServlet บน Google App Engine
Listing ที่ 1.1 โปรแกรม TimerServlet.java
package com.thaijavadev.timerproject;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.SimpleTimeZone;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author Administrator
*/
public class TimerServlet extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSSSSS");
fmt.setTimeZone(new SimpleTimeZone(0, ""));
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet TimerServlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Servlet TimerServlet at " + request.getContextPath() + "</h1>");
out.println("<p>The time is: " + fmt.format(new Date()) + "</p>");
out.println("</body>");
out.println("</html>");
การพัฒนาโปรแกรมเว็บโดยใช้ Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan
12. 12
out.close();
}
// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the
code.">
/**
* Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Returns a short description of the servlet.
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}
Listing ที่ 1.2 โปรแกรม web.xml ที่จะต้องเพิ่ม
….
<servlet>
<servlet-name>TimerServlet</servlet-name>
<servlet-class>com.thaijavadev.timerproject ใ TimerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TimerServlet</servlet-name>
<url-pattern>/TimerServlet</url-pattern>
</servlet-mapping>
...
การพัฒนาโปรแกรมเว็บโดยใช้ Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan
13. 13
1.5 การพัฒนาโปรแกรมเพื่อติดต่อกับ Google Account
Google App Engine มีชุดคำสั่ง API เพื่อให้นักพัฒนาสามารถเรียกใช้ Application ต่างๆของ Google
ได้ รวมถึงเชื่อมต่อกับ Google Account ขั้นตอนนี้จะเป็นการใช้คำสั่งใน Google API ของคลาส User และ
UserService เพื่อติดต่อกับ Google Account โดยจะมีขั้นตอนดังนี้
1. เลือกหน้าต่าง Projects แล้วคลิ๊กขวาที่โหนด thaijavaapp จากนั้นเลือกคำสั่ง New > Java Class...
2. กำหนดค่า Class Name เป็น GoogleTimerServlet และ Package เป็น
com.thaijavadev.timerproject แล้วกด Finish
3. ปรับปรุงโปรแกรม GoogleTimerServlet.java ให้เป็นไปดัง Listing ที่ 1.3
4. ทำการ deploy บน Google App Engine แล้วทดลองรันโปรแกรมที่
http://thaijavaapp.appspot.com/GoogleTimerServlet จะได้ผลลัพธ์ดังรูปที่ 1.7 และ 1.8
รูปที่ 1.7 ผลลัพธ์การัรนโปรแกรม GoogleTimerServlet บน Google App Engine
การพัฒนาโปรแกรมเว็บโดยใช้ Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan
14. 14
รูปที่ 1.8 ผลลัพธ์การัรนโปรแกรม TimerServlet หลังจากการทำ signin
Listing ที่ 1.3 โปรแกรม GoogleTimerServlet.java
package timer;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.SimpleTimeZone;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GoogleTimerServlet extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSSSSS");
fmt.setTimeZone(new SimpleTimeZone(0, ""));
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
String url = request.getRequestURI();
String msg;
if (user != null) {
msg = "<p>Welcome, " + user.getNickname() + "! You can <a href="" +
userService.createLogoutURL(url) +
"">sign out</a>.</p>";
} else {
msg = "<p>Welcome! <a href="" + userService.createLoginURL(url) +
การพัฒนาโปรแกรมเว็บโดยใช้ Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan
15. 15
"">Sign in or register</a> to customize.</p>";
}
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet TimerServlet</title>");
out.println("</head>");
out.println("<body>");
out.println(msg);
out.println("<h1>Servlet TimerServlet at " + request.getContextPath() + "</h1>");
out.println("<p>The time is: " + fmt.format(new Date()) + "</p>");
out.println("</body>");
out.println("</html>");
out.close();
}
// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the
code.">
/**
* Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Returns a short description of the servlet.
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}
การพัฒนาโปรแกรมเว็บโดยใช้ Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan
16. 16
Exercise 2 การใช้ Mail API และ URLFetch บน GAE
แบบฝึกหัดนี้เป็นตัวอย่างการใช้ Services ของ Google App Engine โดยจะพัฒนาโปรแกรมขึ้นมาสอง
โปรแกรมคือ EmailSenderServlet.java เพื่อใช้ Mail API ในการส่ง E-mail จาก Google Account ของผู้ใช้ที่
Login เข้ามา และโปรแกรม DictionaryServlet.java เพื่อใช้ URL Fetch API ในการเรียก url ของ Dictionary
Service
2.1 การพัฒนาโปรแกรมการส่ง Email
Google App Engine สามารถที่จะเรียกใช้ Mail API เพื่อส่ง Mail ได้ โดยในที่นี้จะใช้ User Account
ของ Gmail ในการส่ง โปรแกรมนี้จะมีสองส่วนคือ MailSender.html สำหรับแบบฟอร์มส่ง และ และ
EmailSenderServlet.java ซึ่งเป็นโปรแกรม Servlet ที่ใช้ในการส่ง mail จาก Google Account
2.1.1 การพัฒนาโปรแกรม MailSender.html
โปรแกรม MailSender.html เป็นเว็บเพจที่ใช้แสดงฟอร์มสำหรับให้ผู้ใช้ป้อน E-mail, Subject และ
ข้อความที่จะส่ง โดยมีขั้นตอนการพัฒนาดังนี้
1. เลือกหน้าต่าง Projects แล้วคลิ๊กขวาที่โหนด thaijavaapp > war จากนั้นเลือกคำสั่ง New > Other…
2. ในไดอะล็อก New File ให้เลือก Categories ที่ชื่อ Web เลือก File Types: เป็น HTML แล้วกด Next
3. กำหนด File Name: เป็น MailSender.html แล้วกด Finish
4. เขียน source code ของไฟล์ findBook.html ตาม Listing ที่ 2.1 โดยเราสามารถที่จะลาก icon ประเภท
HTML Forms ที่อยู่ในหน้าต่าง Palette เพื่อสามารถให้เขียนโปรแกรมได้ง่ายขึ้น
Listing 2.1 โปรแกรม MailSender.html
<html>
<head>
<title>Mail Sender</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<h1>E-mail Service </h1>
<form action="/EmailSenderServlet" method="POST">
To : <input name="mailTo" size="25" /> <br> <br>
Subject : <input name="subject" size="80"/><br> <br>
Message : <br>
<textarea name="mailBody" cols=80 rows=5 ></textarea> <br>
<input type="Submit" value="Send"/>
</form>
</body>
</html>
การใช้ Mail API และ URLFetch บน GAE Thanachart Numnonda / Thanisa Kruawaisayawan
17. 17
2.1.2 การพัฒนาโปรแกรม EmailSenderServlet.java
โปรแกรม EmailSenderServlet จะอ่านค่าพารามิเตอร์ที่ส่งมาจากไฟล์ MailSender.html โดยผู้ใช้จะต้อง
ทำการ signin โดยใช้ Google Account ก่อน โดยจะมีขั้นตอนการพัฒนาดังนี้
1. เลือกหน้าต่าง Projects แล้วคลิ๊กขวาที่โหนด thaijavaapp จากนั้นเลือกคำสั่ง New > Java Class...
2. กำหนดค่า Class Name เป็น EmailSenderServlet และ Package เป็น
com.thaijavadev.mailproject แล้วกด Finish
3. ปรับปรุงโปรแกรม EmailSenderServlet.java ให้เป็นไปดัง Listing ที่ 2.2
4. เพิ่ม tag <servlet> ในไฟล์ web.xml ดัง Listing ที่
5. ทำการ deploy บน Google App Engine แล้วทดลองรันโปรแกรมที่2.3
http://thaijavaapp.appspot.com/MailSender.html จะได้แบบฟอร์มดังรูปที่ 2.1
6. ทดลองส่ง E-mail แล้วตรวจสอบว่าผู้รับได้รับจาก Google Account หรือไม่
การใช้ Mail API และ URLFetch บน GAE Thanachart Numnonda / Thanisa Kruawaisayawan
18. 18
รูปที่ 2.1 ผลลัพธ์การรันโปรแกรม MailSender.html บน Google App Engine
Listing ที่ 2.2 โปรแกรม GoogleTimerServlet.java
package com.thaijavadev.mailproject;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class EmailSenderServlet extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>E-mail Service</title>");
การใช้ Mail API และ URLFetch บน GAE Thanachart Numnonda / Thanisa Kruawaisayawan
19. 19
out.println("</head>");
out.println("<body>");
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
String url = request.getRequestURI();
if (user != null) {
String mailTo = request.getParameter("mailTo");
String mailSubject = request.getParameter("subject");
String mailBody = request.getParameter("mailBody");
Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);
try {
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(user.getEmail()));
msg.addRecipient(Message.RecipientType.TO,
new InternetAddress(mailTo));
msg.setSubject(mailSubject);
msg.setText(mailBody);
Transport.send(msg);
out.println("Mail suceesfully send");
} catch (AddressException ex) {
ex.printStackTrace();
} catch (MessagingException ex) {
ex.printStackTrace();
}
} else {
out.println("<p>Welcome! <a href="" + userService.createLoginURL(url)
+ "">Sign in or register</a> to customize.</p>");
}
out.println("</body>");
out.println("</html>");
out.close();
}
}
Listing ที่ 2.3 โปรแกรม web.xml ที่จะต้องเพิ่ม
….
<servlet>
<servlet-name>EmailSenderServlet</servlet-name>
<servlet-class>com.thaijavadev.mailproject.EmailSenderServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>EmailSenderServlet</servlet-name>
<url-pattern>/EmailSenderServlet</url-pattern>
</servlet-mapping>
...
2.2 การพัฒนาโปรแกรมเพื่อค้นหาความหมายของคำ
ขั้นตอนนี้จะเป็นการพัฒนาโปรแกรมเพื่อใช้ในการค้นหาความหมายของคำจาก Dictionary Service ซึ่ง
เป็น RESTful Web Services ที่อยู่ที่ http://services.aonaware.com/DictService/DictService.asmx และ
จะแสดงผลลัพธ์ออกทาง Servlet แต่เนื่องจาก Google App Engine มีข้อจำกัดในการที่จะเรียกใช้ URL ใด
การใช้ Mail API และ URLFetch บน GAE Thanachart Numnonda / Thanisa Kruawaisayawan
20. 20
โดยตรง ดังนั้นโปรแกรมนี้จะเรียกใช้ URL Fetch API เพื่อดึงข้อมูลจาก web site ดังกล่าวมาแสดงผล
โปรแกรมในแบบฝึกหัดนี้มีสองส่วนคือ WordSearch.html ดังแสดงใน Listing ที่ 2.4 และโปรแกรม
DisctonaryServlet.java ดังแสดงใน Listing ที่ 2.5 ซึ่งโปรแกรมนี้จะมีขั้นตอนการพัฒนาเหมือนกับโปรแกรม
การส่ง Email และจะได้ผลัพธ์ดังตัวอย่างในรูปที่ 2.2 และ 2.3
Listing 2.4 โปรแกรม WordSearch.html
<html>
<head>
<title>Word Search</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<h1>Dictionary Service </h1>
<form action="/DictionaryServlet" method="POST">
Lookup meaning of word : <input name="word" size="25" /> <br> <br>
<input type="Submit" value="Lookup"/>
</form>
</body>
</html>
Listing ที่ 2.5 โปรแกรม DictionaryServlet.java
package services;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DictionaryServlet extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String lookupWord = request.getParameter("word");
String urlStr = "http://services.aonaware.com/DictService/DictService.asmx/Define?word="
+ lookupWord;
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet DictionaryServlet</title>");
out.println("</head>");
out.println("<body>");
การใช้ Mail API และ URLFetch บน GAE Thanachart Numnonda / Thanisa Kruawaisayawan
21. 21
URL url = new URL(urlStr);
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
StringBuffer responseData = new StringBuffer();
while ((line = reader.readLine()) != null) {
responseData.append(line + "<br>");
}
reader.close();
out.println(responseData);
out.println("</body>");
out.println("</html>");
out.close();
}
การใช้ Mail API และ URLFetch บน GAE Thanachart Numnonda / Thanisa Kruawaisayawan
22. 22
}
รูปที่ 2.2 ตัวอย่างการค้นหาความหมายของคำว่า Google
รูปที่ 2.3 ผลลัพธ์จากการค้นหาที่รันบน Google App Engine
การใช้ Mail API และ URLFetch บน GAE Thanachart Numnonda / Thanisa Kruawaisayawan
23. 23
Exercise 3 การใช้ Datastore ของ GAE โดยใช้ JPA
เนื้อหาที่ต้องศึกษาก่อน
• การพัฒนาโปรแกรมเว็บโดยใช้ Google App Engine
• Java Persistence API
การเก็บข้อมูลลงในโปรแกรม Web Application ที่จะต้องการรองรับผู้ใช้จำนวนมากเป็นเรื่องค่อนข้างยาก
เนื่องจากผู้ใช้จะต้องเรียกใช้โปรแกรมจาก Web Server จำนวนหลายเครื่องจึงอาจทำให้การเรียกใช้โปรแกรมแต่ละ
ครั้งใช้ Web Server ที่ไม่ซ้ำกัน และ Web Server ทุกเครื่องจะต้องสามารถติดต่อกับข้อมูลที่อาจกระจายอยู่ใน
เครื่องแม่ข่ายหลายๆเครื่องได้ Google App Engine มีกลไกในการจัดการ Infrastructure เพื่อทำให้นักพัฒนา
โปรแกรมไม่ต้องกังวลกับการจัดการปัญหาเหล่านั้น โดยสามารถที่จะจัดการข้อมูลได้โดบผ่าน API ที่ทาง Google
กำหนดไว้ให้
Google App Engine สนับสนุนการเขียนโปรแกรมการจัดการฐานข้อมูลโดยการกำหนดมาตรฐานไว้สอง
แบบคือ Java Data Objects (JDO) และ Java Persistence API (JPA) ซึ่งทั้งสองแบบนี้จะใช้แพลตฟอร์มของ
DataNucleus Access การเก็บข้อมูลวิธีนี้จะใช้วิธีแบบ Object Database ซึ่งแตกต่างจาก RDBMS ทั่วๆไป ดัง
นั้นผู้พัฒนาโปรแกรมที่ใช้ RDBMS อาจจะต้องปรับแนวคิดการเก็บข้อมูลใหม่เพื่อให้พัฒนา Google Web
Application เป็นไปได้ง่ายขึ้น
แบบฝึกหัดนี้จะเป็นตัวอย่างการเก็บข้อมูลผู้เข้ามาชมเว็บเพจ (Guestbook) โดยใช้ JPA โดยโปรแกรมจะ
ทำการสร้าง Entity ที่ชื่อ GuestList แล้วเขียนโปรแกรมเพื่อเก็บและแสดงข้อมูลของผู้เข้ามาชม โดยใช้ Google
Account ในการ signin
3.1 การสร้าง Persistence Unit
แบบฝึกหัดนี้จะสร้าง Persistence Unit จากไฟล์ persistence.xml โดยตรง ซึ่งมีขั้นตอนดังนี้
1. เลือกหน้าต่าง Projects แล้วคลิ๊กขวาที่โหนด thaijavaapp > src > META-INF จากนั้นเลือกคำสั่ง
New > Other...
2. ในไดอะล็อก New ให้เลือก Categories ที่ชื่อ XML เลือก File Types: เป็น XML File แล้วกด Next
3. กำหนดค่า File Name: เป็น persistence.xml แล้วกด Finish
4. ปรับปรุง sourcecode ของ persistence.xml ให้เป็นดัง Listing ที่ 3.1
Listing ที่ 3.1 โปรแกรม persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="thaijavaappPU" transaction-type="RESOURCE_LOCAL">
<provider>org.datanucleus.store.appengine.jpa.DatastorePersistenceProvider</provider>
<non-jta-data-source/>
การใช้ Datastore ของ GAE โดยใช้ JPA Thanachart Numnonda / Thanisa Kruawaisayawan
24. 24
<properties>
<property name="datanucleus.ConnectionURL" value="appengine"/>
<property name="datanucleus.NontransactionalRead" value="true"/>
<property name="datanucleus.NontransactionalWrite" value="true"/>
</properties>
</persistence-unit>
</persistence>
3.2 การพัฒนาโปรแกรม GuestList Entity Class
โปรแกรม GuestList จะเป็น Entity Class ที่ประกอบไปด้วยฟิลด์ต่างๆคือ
● id เป็นข้อมูลชนิด String และเป็น PrimaryKey (id)
● author เป็นข้อมูลชนิด com.google.appengine.api.users.User
● date เป็นข้อมูลชนิด java.util.Date
● content เป็นข้อมูลชนิด String
โปรแกรมนี้มีขั้นตอนการพัฒนาดังนี้
1. เลือกหน้าต่าง Projects แล้วคลิ๊กขวาที่โหนด thaijavaapp จากนั้นเลือกคำสั่ง New > Class
2. กำหนดค่า Class Name เป็น GuestList และ Package เป็น entity แล้วกด Finish
3. ปรับปรุงโปรแกรม ให้มี sourcecode ดัง Listing ที่ 3.2
Listing ที่ 3.2 sourcecode สำหรับโปรแกรม GuestList.java
package entity;
import com.google.appengine.api.users.User;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Temporal;
@Entity
public class GuestList implements Serializable {
private static final long serialVersionUID = 1L;
public GuestList() {
}
public GuestList(User author, String content, Date date) {
this.id = author.getEmail();
this.author = author;
this.content = content;
this.visitDate = date;
}
@Id
private String id;
@Basic
private User author;
การใช้ Datastore ของ GAE โดยใช้ JPA Thanachart Numnonda / Thanisa Kruawaisayawan
25. 25
private String content;
@Temporal(javax.persistence.TemporalType.DATE)
private Date visitDate;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof GuestList)) {
return false;
}
GuestList other = (GuestList) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "entity.GuestList[id=" + id + "]";
}
/**
* @return the author
*/
public User getAuthor() {
return author;
}
/**
* @param author the author to set
*/
public void setAuthor(User author) {
this.author = author;
}
/**
* @return the content
*/
public String getContent() {
return content;
}
/**
* @param content the content to set
*/
การใช้ Datastore ของ GAE โดยใช้ JPA Thanachart Numnonda / Thanisa Kruawaisayawan
26. 26
public void setContent(String content) {
this.content = content;
}
/**
* @return the visitDate
*/
public Date getVisitDate() {
return visitDate;
}
/**
* @param visitDate the visitDate to set
*/
public void setVisitDate(Date visitDate) {
this.visitDate = visitDate;
}
}
3.3 การพัฒนาโปรแกรม EMF.java
โปรแกรม Web Application จะติดต่อกับ Datastore โดยใช้ออปเจ็คชนิด EntityManager โดยสร้างมา
จาก EntityManagerFactory โปรแกรม EMF.java เป็นโปรแกรมที่พัฒนาขึ้นมาเพื่อสร้างออปเจ็คดังกล่าว โดยมี
ขั้นตอนการพัฒนาโปรแกรมดังนี้
1. เลือกหน้าต่าง Projects แล้วคลิ๊กขวาที่โหนด thaijavaapp จากนั้นเลือกคำสั่ง New > Class...
2. ในไดอะล็อก New Java Class กำหนดค่า Class Name เป็น EMF และ Package เป็น entity แล้วกด
Finish
3. ปรับปรุงโปรแกรม EMF.java ให้เป็นไปดัง Listing ที่ 3.3
Listing ที่ 3.3 sourcecode สำหรับโปรแกรม EMF.java
package entity;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class EMF {
private static final EntityManagerFactory emfInstance =
Persistence.createEntityManagerFactory("thaijavaappPU");
private EMF() {
}
public static EntityManagerFactory get() {
return emfInstance;
}
}
การใช้ Datastore ของ GAE โดยใช้ JPA Thanachart Numnonda / Thanisa Kruawaisayawan
27. 27
3.4 การพัฒนาโปรแกรม SignGuestListServlet เพื่อรันบน Google App Engine
ขั้นตอนนี้จะเป็นการพัฒนาโปรแกรม Java Servlet เพื่อเก็บข้อมูลของผู้ใช้ลงใน Datastore ที่ชื่อ
GuestList โดยมีขั้นตอนการพัฒนาโปรแกรมดังนี้
1. เลือกหน้าต่าง Projects แล้วคลิ๊กขวาที่โหนด thaijavaapp จากนั้นเลือกคำสั่ง New > Class
2. ในไดอะล็อก New Servlet กำหนดค่า Class Name เป็น SignGuestListServlet และ Package เป็น
com.thaijavadev.timer แล้วกด Finish
3. ปรับปรุงโปรแกรม SignGuestListServlet.java ให้เป็นไปดัง Listing ที่ 3.4
4. ปรับปรุง web.xml เพื่อเพิ่ม tag <servlet>
5. ทำการรันโปรแกรมเพื่อทดสอบบน localhost แล้วทำการ deploy บน Google App Engine แล้วทดลอง
รันโปรแกรมที่ http://thaijavaapp.appspot.com/SignGuestListServlet จะได้ผลลัพธ์ดังรูปที่ 3.1
รูปที่ 3.1 ผลลัพธ์การรันโปรแกรม SignGuestListServlet บน Google App Engine
Listing ที่ 3.4 โปรแกรม SignGuestListServlet.java
package com.thaijavadev.timer;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import entity.EMF;
import entity.GuestList;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import javax.persistence.EntityManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
การใช้ Datastore ของ GAE โดยใช้ JPA Thanachart Numnonda / Thanisa Kruawaisayawan
28. 28
* @author Administrator
*/
public class SignGuestListServlet extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
String content = request.getParameter("content");
Date date = new Date();
String url = request.getRequestURI();
String msg;
if (user != null) {
msg = "<p>Welcome, " + user.getNickname() + "! You can <a href="" +
userService.createLogoutURL(url) +
"">sign out</a>.</p>";
} else {
msg = "<p>Welcome! <a href="" + userService.createLoginURL(url) +
"">Sign in or register</a> to customize.</p>";
}
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet TimerServlet</title>");
out.println("</head>");
out.println("<body>");
out.println(msg);
out.println("</body>");
out.println("</html>");
GuestList guest = new GuestList(user, content, date);
EntityManager em = EMF.get().createEntityManager();
try {
em.persist(guest);
} finally {
em.close();
}
out.close();
}
// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the
code.">
/**
* Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
การใช้ Datastore ของ GAE โดยใช้ JPA Thanachart Numnonda / Thanisa Kruawaisayawan
29. 29
processRequest(request, response);
}
/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Returns a short description of the servlet.
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}
3.5 การพัฒนาโปรแกรมเพื่อแสดงรายละเอียด GuestList
ขั้นตอนนี้จะเป็นการเขียนโปรแกรม Servlet เพื่อใช้คำสั่ง JPA ในการแสดงรายละเอียดข้อมูลของ
datastore ที่ชื่อ GuestList โดยจะมีขั้นตอนดังนี้
1. เลือกหน้าต่าง Projects แล้วคลิ๊กขวาที่โหนด thaijavaapp จากนั้นเลือกคำสั่ง New > Servlet...
2. ในไดอะล็อก New Servlet กำหนดค่า Class Name เป็น GuestDisplayServlet และ Package เป็น
timer แล้วกด Finish
3. ปรับปรุงโปรแกรม GuestDisplayServlet.java ให้เป็นไปดัง Listing ที่ 3.5
4. ทำการ deploy บน Google App Engine แล้วทดลองรันโปรแกรมที่
http://thaijavaapp.appspot.com/GusetDisplayServlet จะได้ผลลัพธ์ดังตัวอย่างในรูปที่ 3.2
รูปที่ 3.2 ผลลัพธ์การัรนโปรแกรม GusetDisplayServlet บน Google App Engine
การใช้ Datastore ของ GAE โดยใช้ JPA Thanachart Numnonda / Thanisa Kruawaisayawan
30. 30
Listing ที่ 3.5 โปรแกรม GuestDisplayServlet.java
package timer;
import entity.EMF;
import entity.GuestList;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GuestDisplayServlet extends HttpServlet {
/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
EntityManager em = EMF.get().createEntityManager();
try {
Query query = em.createQuery("SELECT o FROM GuestList AS o");
@SuppressWarnings("unchecked")
List<GuestList> results = (List<GuestList>) query.getResultList();
out.println("<html>");
out.println("<head>");
out.println("<title>List All Guests</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>List All Guests</h1>");
for (Object obj : results) {
GuestList guest = (GuestList) obj;
String nickname;
if (guest.getAuthor() == null) {
nickname = "Anonymous";
} else {
nickname = guest.getAuthor().getNickname();
}
out.println(nickname + " " + guest.getId());
out.println(" " + guest.getContent() + " " + guest.getVisitDate() + "<br>");
}
out.println("</body>");
out.println("</html>");
การใช้ Datastore ของ GAE โดยใช้ JPA Thanachart Numnonda / Thanisa Kruawaisayawan
31. 31
} catch(Exception ex) {
out.println(ex);
} finally {
em.close();
out.close();
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}
การใช้ Datastore ของ GAE โดยใช้ JPA Thanachart Numnonda / Thanisa Kruawaisayawan
32. 32
Exercise 4 การพัฒนาโปรแกรมโดยใช้ Google Web Toolkit
Framework
เนื้อหาที่ต้องศึกษาก่อน
• การพัฒนาโปรแกรมเว็บโดยใช้ Google App Engine
Google Web Toolkit (GWT)เป็น Web Application Framework ที่พัฒนาขึ้นมาโดย Google เพื่อให้
นักพัฒนาโปรแกรมสามารถเขียนโปรแกรม Rich Internet Applications (RIAs) แบบ AJAX โดยไม่ต้องเขียน
โปรแกรมภาษา JavaScript แต่สามารถที่จะใช้ภาษา Java ในการพัฒนาได้โดยตรง
แบบฝึกหัดนี้เป็นการนำโปรแกรม NetBeans เพื่อมาพัฒนาโปรแกรมโดยใช้ GWT Frameworks แล้ว
ทดลองพัฒนาโปรแกรมเบื้องต้นเพื่อทดสอบการทำงานบน Google App Engine
4.1 การสร้าง Web Application Project
ขั้นตอนนี้จะเป็นการโปรแกรม Web Application โดยใช้ GWT Framework ซึ่งจะรันอยู่ภายใต้ Google
App Engine โดยการสร้าง Project ใหม่ขึ้นมา ซึ่งมีขั้นตอนดังนี้
1. เลือกเมนู File => New => Other
2. ในไดอะล็อก New Project ให้เลือก Categories เป็น Google และเลือก Project เป็น Web
Application Project แล้วกด Next
3. กำหนด Project Name เป็น thaigwtapp และกำหนด Package เป็น org.thaijavadev.Main กด
Finish
4.2 โครงสร้างโปรแกรม Google Web Toolkit
โปรแกรมสำหรับ Google Web Toolkit จะประกอบไฟล์ต่างๆสามส่วนที่สำคัญดังนี้
● Module descriptor
● Public resources
● Client-side code
นอกจากนี้เรายังสามารถที่จะเขียนโปรแกรมส่วน Server-side code เพิ่มเติมในกรณีที่ต้องการจะพัฒนา
ส่วน Back-end services
โปรแกรมเว็บในตัวอย่างนี้จะมีโปรแกรมในส่วนต่างๆดังนี้
• Module Descriptor คือไฟล์ Thaiawtapp.gwt.xml ซึ่งจะมีคำสั่งที่สำคัญสองชุดคือ <inherits> ที่เป็น
คำสั่งเสมือนคำสั่ง import ในภาษาจาวา และคำสั่ง <entry-point> เพื่อระบุชื่อคลาสที่เป็น EntryPoint
โดยมีคำสั่งดังนี้
<?xml version="1.0" encoding="UTF-8"?>
<module>
<inherits name="com.google.gwt.user.User"/>
การพัฒนาโปรแกรมโดยใช้ Google Web Toolkit Framework Thanachart Numnonda / Thanisa Kruawaisayawan
33. 33
<entry-point class="org.thaijavadev.Main.client.Thaiawtapp"/>
</module>
• Public Resources คือไฟล์ต่างๆที่จะถูกเรียกใช้ทั่วไปเช่นไฟล์ HTML, ไฟล์ CSS หรือ ไฟล์รูปภาพ ใน
ตัวอย่างนี้คือไฟล์ Thaiawtapp.html ซึ่งจะมีคำสั่ง <script> เพื่อระบุไฟล์ JavaScript ชื่อใช้รัน
โปรแกรม โปรแกรม JavaScript จะถูกสร้างมาจากโปรแกรม Java to JavaScript Compiler โดย
อัตโนมัติจากโปรแกรมภาษาจาวาที่เราพัฒนาขึ้น
• Client-side code คือโปรแกรม Thaiawtapp.java ซึ่งโปรแกรมภาษา Java ที่พัฒนาขึ้นแล้วถูกแปลเป็น
โปรแกรม JavaScript โปรแกรมนี้จะเป็นการพัฒนาส่วนติดต่อกับผู้ใช้ (UI; User Interface) ที่ใช้คำสั่ง
API ของ Google Web Toolkit แต่มีลักษณะการพัฒนาโปรแกรมเหมือนคำสั่งแบบ Swing
4.3 การพัฒนาโปรแกรม Client-Side Code
ขั้นตอนนี้จะเป็นการพัฒนาโปรแกรมส่วนติดต่อกับผู้ใช้ของตัวอย่างนี้ให้เป็นไปดังรูปที่ 4.1 แล้วกำหนดว่า
เมื่อผู้ใช้กดปุ่ม Login จะแสดง Dialog Box ขึ้นมาโดยถ้า password ตรงกับคำว่า secret จะได้ผลลัพธ์ดังรูปที่
4.2 แต่ถ้าเป็นค่าอื่นจะได้ดังรูปที่ 4.3
เราสามารถพัฒนาโปรแกรมนี้ได้โดยการปรับปรุง source code ของโปรแกรม Thaiawtapp.java ในส่วน
ของเมธอด onModuleLoad() ให้เป็นไปตาม Listing ที่ 4.1 แล้วติดตั้งโปรแกรมนี้ลงบน Google App Engine
รูปที่ 4.1 ส่วนติดต่อกับผู้ใช้ของโปรแกรมเว็บ
รูปที่ 4.2 ไดอะล็อกบล็อกแสดงการล็อกอินสำเร็จ
การพัฒนาโปรแกรมโดยใช้ Google Web Toolkit Framework Thanachart Numnonda / Thanisa Kruawaisayawan
34. 34
รูปที่ 4.3 ไดอะล็อกบล็อกแสดงการล็อกอินผิดผลาด
Listing ที่ 4.1 sourcecode ของเมธอด onModuleLoad() ที่ปรับปรุงใหม่
public void onModuleLoad() {
final TextBox username = new TextBox();
final PasswordTextBox password = new PasswordTextBox();
final Button button = new Button("Logon");
final VerticalPanel panel = new VerticalPanel();
panel.add(new Label("username"));
panel.add(username);
panel.add(new Label("password"));
panel.add(password);
panel.add(button);
RootPanel.get().add(panel);
button.addClickListener(new ClickListener() {
public void onClick(Widget sender) {
if ("secret".equals(password.getText())) {
Window.alert("Welcome " + username.getText());
} else {
Window.alert("Invalid authentication");
}
}
});
}
นอกจากนี้เราสามารถที่จะปรับ StyleSheet ของการโปรแกรมเว็บนี้ เพื่อให้มีฟอนต์ในการแสดงส่วน
ติดต่อกับผู้ใช้ดังรูปที่ 4.4 โดยแก้ไขไฟล์ Thaiawtapp.css ให้เป็นไปตาม Listing ที่ 4.2
การพัฒนาโปรแกรมโดยใช้ Google Web Toolkit Framework Thanachart Numnonda / Thanisa Kruawaisayawan
35. 35
รูปที่ 4.4 ส่วนติดต่อกับผู้ใช้ที่มีการใช้ Cascade Style Sheet
1.
Listing ที่ 4.2 sourcecode ของโปรแกรม Thaiawtapp.css
root {
display: block;
}
.gwt-Label {
font-size: 9px;
}
.gwt-Button, .gwt-TextBox, .gwt-PasswordTextBox {
font-size: 9px;
height: 19px;
width: 75px;
}
การพัฒนาโปรแกรมโดยใช้ Google Web Toolkit Framework Thanachart Numnonda / Thanisa Kruawaisayawan
36. 36
Exercise 5 GWT : Client/Server Communication
เนื้อหาที่ต้องศึกษาก่อน
• การพัฒนาโปรแกรมโดยใช้ Google Web Toolkit Framework
GWT มีวิธีการที่จะพัฒนาโปรแกรมที่จะติดต่อระหว่าง Client กับ Server คือ RPC (Remote
Procedure Call) โดยจะต้องมีการพัฒนาโปรแกรมจาวาที่เป็น Interface และ Class ต่างๆที่เกี่ยวข้อง
แบบฝึกหัดนี้เป็นการพัฒนาโปรแกรม GWT-RPC โดยการทดลองสร้าง Service สำหรับการแสดง
ข้อความแบบสุ่ม (Random Quote Generator) จากนั้นจะทดสอบการรันโปรแกรมบน Development Server
ก่อนที่จะติดตั้งลงบน Google App Engine
5.1 การพัฒนา Random Quote Service
ขั้นตอนนี้จะเป็นการปรับปรุง GWT-RPC ที่พัฒนาขึ้น เพื่อให้ Server ส่งข้อความแบบสุ่มกลับมาแสดง
ยังเครื่อง Client เมื่อมีการเรียกใช้ Service โดยจะมีขั้นตอนดังนี้
1. ปรับปรุงโปรแกรม GreetingServiceImpl.java ให้เป็นไปดัง Listing ที่ 5.1
2. ปรับปรุงโปรแกรม GreetingService.java และ GreetingServiceAsync.java เพื่อให้มี interface
method ดังนี้
String myMethod(String s) throws IllegalArgumentException;
3. ในโปรแกรม Thaiawtapp.java ให้กำหนด แล้วปรับปรุงเมธอด onModuleLoad() ให้เป็นไปดัง
Listing ที่ 5.1 ซึ่งจะต้องทำการ import คลาสต่างๆที่เกี่ยวข้องให้ถูกต้อง (import
com.google.gwt.user.client.Timer;)
4. รันโปรเจ็ค thaigwtapp จะได้ผลลัพธ์เป็นข้อความสุ่มที่เปลี่ยนแปลงไปเรื่อยๆดังรูปที่ 5.1
5. ทำการ deploy บน Google App Engine แล้วทดลองเรียกโปรแกรมจาก url ที่ http://thaigwtapp
.appspot.com
รูปที่ 5.1 ผลลัพธ์การรันโปรแกรม Random Quote Generator
GWT : Client/Server Communication Thanachart Numnonda / Thanisa Kruawaisayawan
37. 37
Listing ที่ 5.1 โปรแกรม GreetingServiceImpl.java
package org.thaijavadev.Main.server;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.thaijavadev.Main.client.GreetingService;
import org.thaijavadev.Main.shared.FieldVerifier;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
/**
* The server side implementation of the RPC service.
*/
@SuppressWarnings("serial")
public class GreetingServiceImpl extends RemoteServiceServlet implements
GreetingService {
private Random randomizer = new Random();
private static final long serialVersionUID = -15020842597334403L;
private static List quotes = new ArrayList();
static {
quotes.add("No great thing is created suddenly - Epictetus");
quotes.add("Well done is better than well said - Ben Franklin");
quotes.add("No wind favors he who has no destined port - Montaigne");
quotes.add("Sometimes even to live is an act of courage - Seneca");
quotes.add("Know thyself - Socrates");
}
public String myMethod(String s) {
return (String) quotes.get(randomizer.nextInt(5));
}
}
Listing ที่ 5.2 sourcecode ของเมธอด onModuleLoad() ที่ปรับปรุงใหม่
public void onModuleLoad() {
final Label quoteText = new Label();
Timer timer = new Timer() {
public void run() {
//create an async callback to handle the result:
AsyncCallback callback = new AsyncCallback() {
public void onFailure(Throwable arg0) {
//display error text if we can't get the quote:
quoteText.setText("Failed to get a quote");
}
public void onSuccess(Object result) {
GWT : Client/Server Communication Thanachart Numnonda / Thanisa Kruawaisayawan
38. 38
//display the retrieved quote in the label:
quoteText.setText((String) result);
}
};
greetingService.myMethod(null, callback);
}
};
timer.scheduleRepeating(1000);
RootPanel.get().add(quoteText);
}
}
GWT : Client/Server Communication Thanachart Numnonda / Thanisa Kruawaisayawan
39. 39
Exercise 6 การพัฒนาโปรแกรม RIA ที่เรียกใช้ Web Services
แบบฝึกหัดนี้เป็นตัวอย่างการพัฒนาโปรแกรม GWT-RPC โดยการเรียกใช้ Web Services ของ
Dictionary Service ที่พัฒนาขึ้นในแบบฝึกหัดที่ 2 โดยแทนที่จะพัฒนา Traditional Client แบบที่เรียกใช้ไฟล์
HTML แต่จะมาพัฒนาโปรแกรมแบบ Rich Internet Application โดยใช้ GWT-RPC
6.1 การเพิ่มเมธอด Service ของโปรแกรม GWT-RPC
ขั้นตอนนี้จะเป็นการเพิ่มเซอร์วิสของโปรแกรม GWT-RPC ที่พัฒนาในแบบฝึกหัดที่ผ่านมาอีกหนึ่งเมธอด
ชื่อ searchWord ในกรณีนี้จะต้องปรับปรุงไฟล์ทั้งหมดสามไฟล์คือ GreetingService.java,
GreetingServiceAsync.java และ GreetingServiceImpl.java โดยมีขั้นตอนการพัฒนาดังนี้
1. ปรับปรุง interface ที่ชื่อ GreetingService.java โดยเพิ่มคำประกาศเมธอดดังนี้
public String searchWord(String s);
2. ปรับปรุง interface ที่ชื่อ GreetingServiceAsync.java โดยเพิ่มคำประกาศเมธอดดังนี้
public void searchWord(String s, AsyncCallback<String> callback);
3. ปรับปรุง source code ของไฟล์ GreetingServiceImpl.java โดยการ implement เมธอดที่ชื่อ
searchWord ตาม Listing ที่ 6.1
Listing ที่ 6.1 sourcecode ของเมธอด searchWord
public String searchWord(String s) {
try {
String urlStr =
"http://services.aonaware.com/DictService/DictService.asmx/Define?word=" + s;
URL url = new URL(urlStr);
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
StringBuffer responseData = new StringBuffer();
while ((line = reader.readLine()) != null) {
responseData.append(line + "<br>");
}
reader.close();
return responseData.toString();
} catch (IOException ex) {
return "error";
การพัฒนาโปรแกรม RIA ที่เรียกใช้ Web Services Thanachart Numnonda / Thanisa Kruawaisayawan
40. 40
}
}
6.2 การปรับปรุงโปรแกรม Thaiawtapp.java
ขั้นตอนนี้จะเป็นการแก้ไขโปรแกรม Thaiawtapp.java เพื่อให้แสดงผลลัพธ์ดังตัวอย่างในรูปที่ และเมื่อกด
ปุ่ม Lookup โปรแกรมก็จะแสดงผลลัพธ์แบบ Partial Screen Update โดยการแทรกความหมายของคำที่ค้นหาดัง
ตัวอย่างในรูปที่ โดยมีขั้นตอนการพัฒนาดังนี้
1. ปรับปรับปรุงโปรแกรม Thaiwatapp.java ให้เป็นไปดัง Listing ที่ 6.2
2. รันโปรเจ็ค thaigwtapp จะได้ผลลัพธ์ดังตัวอย่างในรูปที่ 5.1 และ
3. ทำการ deploy บน Google App Engine แล้วทดลองเรียกโปรแกรมจาก url ที่ http://thaigwtapp
.appspot.com
Listing ที่ 6.2 sourcecode ของโปรแกรม Thaiawtappjava
public void onModuleLoad() {
InlineLabel label = new InlineLabel("Lookup meaning of Word");
final TextBox text = new TextBox();
// final TextArea ta = new TextArea();
// ta.setPixelSize(600, 400);
final HTML ta = new HTML();
Button bn = new Button("Lookup");
VerticalPanel panel = new VerticalPanel();
panel.add(label);
panel.add(text);
panel.add(bn);
panel.add(ta);
RootPanel.get().add(panel);
final AsyncCallback callback = new AsyncCallback() {
public void onFailure(Throwable arg0) {
//display error text if we can't get the quote:
ta.setHTML("Failed to get a quote");
}
public void onSuccess(Object result) {
//display the retrieved quote in the label:
การพัฒนาโปรแกรม RIA ที่เรียกใช้ Web Services Thanachart Numnonda / Thanisa Kruawaisayawan
41. 41
ta.setHTML((String) result);
}
};
bn.addClickHandler(new ClickHandler(){
public void onClick(ClickEvent event) {
greetingService.searchWord(text.getText(), callback);
}
});
}
การพัฒนาโปรแกรม RIA ที่เรียกใช้ Web Services Thanachart Numnonda / Thanisa Kruawaisayawan
43. 43
รูปที่ 6.1 ผลลัพธ์การรันโปรแกรม SearchWord
การพัฒนาโปรแกรม RIA ที่เรียกใช้ Web Services Thanachart Numnonda / Thanisa Kruawaisayawan
44. 44
รูปที่ 6.2 ผลลัพธ์การรันโปรแกรม SearchWord
การพัฒนาโปรแกรม RIA ที่เรียกใช้ Web Services Thanachart Numnonda / Thanisa Kruawaisayawan