google app engine using eclipse
Post on 12-May-2015
17.391 Views
Preview:
DESCRIPTION
TRANSCRIPT
1
Hand-onExercises
การพฒนาโปรแกรมWeb Programmingบน Cloud Computing
โดยใชGoogle App Engine
Assoc. Prof. Dr.Thanachart Numnondaand
Asst Prof.Thanisa Kruawaisayawan
Mini Master of Java TechnologyFaculty of Information Technology
King Mongkut Institute of Technology Ladkrabang
August 2011
Thanachart Numnonda / Thanisa Kruawaisayawan
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
สารบญ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
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
รปท 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 ตวอยางผลลพธการรนโปรแกรม guestbook
1.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
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
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
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
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
รปท 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
"\">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
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
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
รปท 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
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.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
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 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
<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;
@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 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
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
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
* @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
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
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
} 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 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
<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
รปท 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.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
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
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
//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-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
} }
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
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
รปท 6.1 ผลลพธการรนโปรแกรม SearchWord
การพฒนาโปรแกรม RIA ทเรยกใช Web Services Thanachart Numnonda / Thanisa Kruawaisayawan
top related