• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
๋Java Web Programming on Cloud Computing using Google App Engine
 

๋Java Web Programming on Cloud Computing using Google App Engine

on

  • 20,128 views

เอกสารประกอบการอบรมหลักสูตร Mini Master of Java Technology ปี 2011 เรื่อง Java Web Programming on Cloud Computing using Google App ...

เอกสารประกอบการอบรมหลักสูตร Mini Master of Java Technology ปี 2011 เรื่อง Java Web Programming on Cloud Computing using Google App Engine โดยใช้ Eclipse เป็น Tool

Statistics

Views

Total Views
20,128
Views on SlideShare
20,128
Embed Views
0

Actions

Likes
3
Downloads
120
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    ๋Java Web Programming on Cloud Computing using Google App Engine ๋Java Web Programming on Cloud Computing using Google App Engine Document Transcript

    • 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 TechnologyKing Mongkut Institute of Technology Ladkrabang August 2011 Thanachart Numnonda / Thanisa Kruawaisayawan
    • 2Thanachart Numnonda / Thanisa Kruawaisayawan
    • 3 บทนำ เอกสารนี้ใช้ในการประกอบการสอนวิชา Java 301 : EJB 3.0 and Google App Engines ของหลักสูตร Mini Master of Java Technology คณะเทคโนโลยีสารสนเทศ สถาบันพระจอมเกล้าเจ้าคุณทหารลาดกระบัง โดยมีจุดประสงค์เพื่อให้ผู้เรียนได้เข้าใจถึงการพัฒนาโปรแกรม Web Application บน CloudComputing ที่รับโดยใช้ 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 สารบัญExercise 1 การพัฒนาโปรแกรมเว็บโดยใช้ Google App Engine.............................................................. 4Exercise 2 การใช้ Mail API และ URLFetch บน GAE....................................................................... 16Exercise 3 การใช้ Datastore ของ Google App Engine โดยใช้ Java Persistence API (JPA).................22Exercise 4 การพัฒนาโปรแกรมโดยใช้ Google Web Toolkit Framework.............................................34Exercise 5 GWT : Client/Server Communication........................................................................... 42Exercise 6 การพัฒนาโปรแกรม RIA ที่เรียกใช้ Web Services............................................................... 46 Thanachart Numnonda / Thanisa Kruawaisayawan
    • 5 Exercise 1 การพัฒนาโปรแกรมเว็บโดยใช้ Google App Engine แบบฝึกหัดนี้เป็นการพัฒนาโปรแกรม Web Application โดยจะติดตั้งและรันโปรแกรมอยู่บน GoogleApp Engine ซึ่งใช้ Infrastructure ของ Google ในการรันโปรแกรม Google App Engine จัดเป็น CloudComputing ประเภท 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 เป็นแพลตฟอร์มที่ให้นักพัฒนาโปรแกรมสามารถรันโปรแกรมเว็บแอปพลิเคชั่นบน Googles Infrastructure ได้ โดยนักพัฒนาจะต้องมี account ของ Google และจะต้องติดตั้ง Google AppEngine 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 รูปที่ 1.1 รายการ Available Softwares 7. โปรแกรมจะประเมินซอฟต์แวร์ต่างๆที่จะต้องติดตั้ง แล้วจะแสดงผลออกมาดังรูป แล้วให้กดปุ่ม Next รูปที่ 1.2 รายละเอียดการติดตั้งการพัฒนาโปรแกรมเว็บโดยใช้ Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan
    • 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 ตัวอย่างผลลัพธ์การรันโปรแกรม guestbook1.3 การติดตั้ง Sample GuestBook Project บน Google App Engine ขั้นตอนนี้จะเป็นการติดตั้ง Sample Project ลงบน Google App Engine ซึ่งมีขั้นตอนดังนี้การพัฒนาโปรแกรมเว็บโดยใช้ Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan
    • 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 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
    • 101.4 การสร้าง Web Application Project ขั้นตอนนี้จะเป็นการพัฒนาโปรแกรม Web Application เพื่อทดลองติดตั้งลง GooglesInfrastructure โดยการสร้าง 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 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 EngineListing ที่ 1.1 โปรแกรม TimerServlet.javapackage 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 out.close(); } // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit thecode."> /** * 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
    • 131.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 รูปที่ 1.8 ผลลัพธ์การัรนโปรแกรม TimerServlet หลังจากการทำ signinListing ที่ 1.3 โปรแกรม GoogleTimerServlet.javapackage 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 "">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 thecode."> /** * 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 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 ของ DictionaryService2.1 การพัฒนาโปรแกรมการส่ง Email Google App Engine สามารถที่จะเรียกใช้ Mail API เพื่อส่ง Mail ได้ โดยในที่นี้จะใช้ User Accountของ Gmail ในการส่ง โปรแกรมนี้จะมีสองส่วนคือ MailSender.html สำหรับแบบฟอร์มส่ง และ และEmailSenderServlet.java ซึ่งเป็นโปรแกรม Servlet ที่ใช้ในการส่ง mail จาก Google Account2.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
    • 172.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 รูปที่ 2.1 ผลลัพธ์การรันโปรแกรม MailSender.html บน Google App EngineListing ที่ 2.2 โปรแกรม GoogleTimerServlet.javapackage 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 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โดยตรง ดังนั้นโปรแกรมนี้จะเรียกใช้ URL Fetch API เพื่อดึงข้อมูลจาก web site ดังกล่าวมาแสดงผล โปรแกรมในแบบฝึกหัดนี้มีสองส่วนคือ WordSearch.html ดังแสดงใน Listing ที่ 2.4 และโปรแกรมDisctonaryServlet.java ดังแสดงใน Listing ที่ 2.5 ซึ่งโปรแกรมนี้จะมีขั้นตอนการพัฒนาเหมือนกับโปรแกรมการส่ง Email และจะได้ผลัพธ์ดังตัวอย่างในรูปที่ 2.2 และ 2.3Listing 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.javapackage 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 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} รูปที่ 2.2 ตัวอย่างการค้นหาความหมายของคำว่า Google รูปที่ 2.3 ผลลัพธ์จากการค้นหาที่รันบน Google App Engineการใช้ Mail API และ URLFetch บน GAE Thanachart Numnonda / Thanisa Kruawaisayawan
    • 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 WebApplication เป็นไปได้ง่ายขึ้น แบบฝึกหัดนี้จะเป็นตัวอย่างการเก็บข้อมูลผู้เข้ามาชมเว็บเพจ (Guestbook) โดยใช้ JPA โดยโปรแกรมจะทำการสร้าง Entity ที่ชื่อ GuestList แล้วเขียนโปรแกรมเพื่อเก็บและแสดงข้อมูลของผู้เข้ามาชม โดยใช้ GoogleAccount ในการ signin3.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.1Listing ที่ 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/persistencehttp://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 <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.2Listing ที่ 3.2 sourcecode สำหรับโปรแกรม GuestList.javapackage 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;@Entitypublic 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 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 wont 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 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.3Listing ที่ 3.3 sourcecode สำหรับโปรแกรม EMF.javapackage 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
    • 273.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 EngineListing ที่ 3.4 โปรแกรม SignGuestListServlet.javapackage 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* @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 thecode."> /** * 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 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
    • 30Listing ที่ 3.5 โปรแกรม GuestDisplayServlet.javapackage 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 } 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 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 Engine4.1 การสร้าง Web Application Project ขั้นตอนนี้จะเป็นการโปรแกรม Web Application โดยใช้ GWT Framework ซึ่งจะรันอยู่ภายใต้ GoogleApp Engine โดยการสร้าง Project ใหม่ขึ้นมา ซึ่งมีขั้นตอนดังนี้ 1. เลือกเมนู File => New => Other 2. ในไดอะล็อก New Project ให้เลือก Categories เป็น Google และเลือก Project เป็น Web Application Project แล้วกด Next 3. กำหนด Project Name เป็น thaigwtapp และกำหนด Package เป็น org.thaijavadev.Main กด Finish4.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 <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 แต่มีลักษณะการพัฒนาโปรแกรมเหมือนคำสั่งแบบ Swing4.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 รูปที่ 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 รูปที่ 4.4 ส่วนติดต่อกับผู้ใช้ที่มีการใช้ Cascade Style Sheet 1.Listing ที่ 4.2 sourcecode ของโปรแกรม Thaiawtapp.cssroot { 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 Exercise 5 GWT : Client/Server Communicationเนื้อหาที่ต้องศึกษาก่อน • การพัฒนาโปรแกรมโดยใช้ Google Web Toolkit Framework GWT มีวิธีการที่จะพัฒนาโปรแกรมที่จะติดต่อระหว่าง Client กับ Server คือ RPC (RemoteProcedure Call) โดยจะต้องมีการพัฒนาโปรแกรมจาวาที่เป็น Interface และ Class ต่างๆที่เกี่ยวข้อง แบบฝึกหัดนี้เป็นการพัฒนาโปรแกรม GWT-RPC โดยการทดลองสร้าง Service สำหรับการแสดงข้อความแบบสุ่ม (Random Quote Generator) จากนั้นจะทดสอบการรันโปรแกรมบน Development Serverก่อนที่จะติดตั้งลงบน Google App Engine5.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 GeneratorGWT : Client/Server Communication Thanachart Numnonda / Thanisa Kruawaisayawan
    • 37Listing ที่ 5.1 โปรแกรม GreetingServiceImpl.javapackage 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 cant get the quote: quoteText.setText("Failed to get a quote"); } public void onSuccess(Object result) {GWT : Client/Server Communication Thanachart Numnonda / Thanisa Kruawaisayawan
    • 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 Exercise 6 การพัฒนาโปรแกรม RIA ที่เรียกใช้ Web Services แบบฝึกหัดนี้เป็นตัวอย่างการพัฒนาโปรแกรม GWT-RPC โดยการเรียกใช้ Web Services ของDictionary Service ที่พัฒนาขึ้นในแบบฝึกหัดที่ 2 โดยแทนที่จะพัฒนา Traditional Client แบบที่เรียกใช้ไฟล์HTML แต่จะมาพัฒนาโปรแกรมแบบ Rich Internet Application โดยใช้ GWT-RPC6.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.1Listing ที่ 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 } }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.comListing ที่ 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 cant 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 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
    • 42การพัฒนาโปรแกรม RIA ที่เรียกใช้ Web Services Thanachart Numnonda / Thanisa Kruawaisayawan
    • 43 รูปที่ 6.1 ผลลัพธ์การรันโปรแกรม SearchWordการพัฒนาโปรแกรม RIA ที่เรียกใช้ Web Services Thanachart Numnonda / Thanisa Kruawaisayawan
    • 44 รูปที่ 6.2 ผลลัพธ์การรันโปรแกรม SearchWordการพัฒนาโปรแกรม RIA ที่เรียกใช้ Web Services Thanachart Numnonda / Thanisa Kruawaisayawan