Google App Engine Using NetBeans (in Thai)

49
1 !" #" $ $ %& # ’# ( # ! $ ) ( # *) %# +,-, Thanachart Numnonda / Thanisa Kruawaisayawan

description

Exercise: Google App Engine Using NetBeans

Transcript of Google App Engine Using NetBeans (in Thai)

Page 1: Google App Engine Using NetBeans (in Thai)

1

�������

����

�������������

� ������� � ���

������������ ������

� ����

� ������ ��������

� ���������� �� ��������� �� �����

���

� ������� ���� ��!��" �� �#�" ��

$ ����$ � �����% �&��� �������#

'�����#����(���� ������� �������#

!����$ ���)���(� ���������� �������#�*��)�����

% ��#�+,-,

Thanachart Numnonda / Thanisa Kruawaisayawan

Page 2: Google App Engine Using NetBeans (in Thai)

2

�����

��������� ����������������������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 ����-��./���%�� �����������'(��#'�!�,�����-��#"����NetBeans 6.8

[email protected] twitter.com/thanachart

www.facebook.com/thanachart www.thaijavadev.com

���0��#�2553

Thanachart Numnonda / Thanisa Kruawaisayawan

Page 3: Google App Engine Using NetBeans (in Thai)

3

������

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

Page 4: Google App Engine Using NetBeans (in Thai)

4

Exercise 1 ��������� ��������������Google App Engine

-��./���%���1����!�,�����-��#�Web Application �%�"���%���-��������-��#���2���Google

App Engine 3+(��� ��Infrastructure ����Google �����������-��#�Google App Engine "�%��1��Cloud

Computing ����4��Platform as a Service (PaaS) �5��� ���!�,��������-��#��#�� �("���%������-��#��-!��6��&#�(����Google "�%����#*� �� ��%����7""$���*% �5���%�API *� ���4�8��'��Java -���Python

-��./���%�"��� �NetBeans ����&��(��6.8 �����!�,�����-��#�5������Google App Engine -���� Google App Engine Plugin Module ����NetBeans #��2�������!�,�����-��#

1.1 ��������� ��������������������� �Google App Engine� �

Google App Engine ��1�-!��6��&#�(�� ���!�,�����-��#��#�� ������-��#��9�-��!������(����Google's Infrastructure *% ��%����!�,��"�� ��#�account ����Google -��"�� ����%����Google App

Engine SDK 3+(���������%����� ����Google App Engine ��#�� %�*% �(http://code.google.com/appengine/ �%������#�� �("���$������������%������-��#�NetBeans �!'(�!�,���Google App Engine *% %����

1. �5�������������App Engine Account �%��� �Google Account �(http://code.google.com/appengine/

2. �5����%���&���%�Google App Engine SDK for Java �(http://code.google.com/appengine/downloads.html

3. �5�����unzip*6�&�(%���&���%��%��5���%*� ��*%��9����(�(��#���#������2��c:\appengine-java-sdk-1.3.5

4. �5������%������-��#�NetBeans version 6.8

5. ������-��#�NetBeans -� ���'���#���Tools > Plugins

6. ��*%���9���Plugins ��'��-���Setting -� ��%�$:#�Add

7. *%���9���Update Center Customizer "�����0�+��� �5���%�2��Name: ��1��Google App Engine

-���2��URL: ��1�http://kenai.com/projects/nbappengine/downloads/download/Latest_NetBeans68/updates.xml %������(�1.1

���!�,�����-��#��9��%��� �Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan

Page 5: Google App Engine Using NetBeans (in Thai)

5

�������1.1������ ������Update Center Customier

8. ��*%���9���Plugins �� ��'��-���Available Plugins -� ���'���Google App Engine Module

(Server, Configuration Editor, Deployment, Editor Hints -���Samples) -� ��%�$:#�Install

9. �����-��#�NetBeans ��'��-���Services -� ���'�����%�Servers ���;������'���Add Server...

10. ��*%���9���Add Server Instance �� ��'���Google App Engine %������(�1.2�-� ��%�Next

�������1.2���������Google App Server

11.�5���%�Server Location ��1��5�-��2��(��%����Google App Engine SDK ��2��C:\appengine-java-

sdk-1.3.5 �%�$:#�Next

12. ��*%���9���� � �%*���� ���2��Server Properties ��#�(�5���%*� �������(�port ������Server �%�#

���!�,�����-��#��9��%��� �Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan

Page 6: Google App Engine Using NetBeans (in Thai)

6

�� �����2���#���#��#���#�-� ��%�Finish

13.�����������""�� ���5���%�2��PATH ��*6�&�appcfg.cmd �(���2��*%��9�����(�C:\appengine-

java-sdk-1.3.5\bin �%��� �!�(#�5���(��!'(����$�PATH ����JDK ������2���@set PATH=C:\ProgramFiles\Java\jdk1.6.0_14\bin

14.���"�����"���%�Error ���������Deploy ����"9��%�"�#� ����#�2��<failed to compile the

generated JSP java files ... Error running javac.exe compiler.” ��������"��1��!������'(����#!������&#�����%����JRE -����1��default ����JAVA Path �����%����Plugin.������� ���5�����9���=>*6�&�javac.exe *��(*%��9����(�bin ������-��#�JRE -��*6�&�tools.jar *��(*%��9����(�lib ������-��#�JRE (��2��c:\Program Files\java\jre6\lib )

1.2 ������ ��� �Sample GuestBook Project� �

�������"���1������ ���Sample Project �(#���2-� ��!'(��%���������Development Server 3+(�#������%���

1. ��'���#���File => New Project..

2. ��*%���9���New Project �� ��'���Categories ��1��Sample > Google App Engine-����'��Projects ��1��Guest Book -� ��%�Next

3. ��'���Project Location ��1��Director �(���� �����"���9�*6�&*� ��%�Finish

4. ���;�����(���%�guestbook -� ���'���5���(��Run "���9�)���!?&������-��#%�������2��������(�

�������1.3����������������������� ����guestbook

1.3 ���������� �Web Application Project� �

�������"���1����!�,�����-��#�Web Application �!'(��%�����%������Google's

���!�,�����-��#��9��%��� �Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan

Page 7: Google App Engine Using NetBeans (in Thai)

7

Infrastructure�%������ ���Project ��#2�+�#�����3+(�#������%���

1. ��'���#���File => New Project..

2. ��*%���9���New Project �� ��'���Categories ��1��Java Web -����'���Project ��1��Web

Application -� ��%�Next

3. �5���%�Project Name ��1��thaijavaapp -� ���'���Project Location ��1��Director �(���� �����"���9�*6�&*� ��%�Next

4. "�������'���Server ��1��Google App Engine -� ��%�Finish

5. ���-��#�Plugin ����NetBeans "���%����Library �("5���1�� ���� ���Google App Engine SDK %������(�1.4

�������1.4�Library �������!"�#���$�Google App Engine

���!�,�����-��#��9��%��� �Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan

Page 8: Google App Engine Using NetBeans (in Thai)

8

6. ����"9��"�#���-��#�index.jsp �!'(�-�%�� ����#�Hello World ���2�����#�� �%����("�������-��#������'(���(!�,��*% �%������'���5���(��Run �%�"�*% )���!?&%������(�1.5

�������1.5���������������� ���!��localhost server

7. ����"9��thaijavapp "�#*6�&"�%����configuration �5���������deploy *�����Google App Engine �(�'(��appengine-web.xml �%�*6�&�"����24���� ���%�myGoogleApp > Configuration Files �%�"�#�2��2��@%������(�1.6

�������1.6 %&���appengine-web.xml

8. �����#�� �("��5�����Deploy ����"9�������Google App Engine �%����*��sign up �� ��account

�������(�Google App Engine�(�https://appengine.google.com/ -� ��%�$:#�Create an

���!�,�����-��#��9��%��� �Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan

Page 9: Google App Engine Using NetBeans (in Thai)

9

Application9. �5���%�2��Application Identifier: ��1��thaijavaapp -���Application Title: ��1��Thai Java

Google App %������(�1.7�-� ��%�$:#�Save

�������1.7���#�'��Application#���$�Google App Engine

10. Google App Engine "�-�%�����'(��Application ��#2�(�5���%�+�%������(�1.8

�������1.8��� # ������My Applications (��Google App Engine

11. �����-��#�NetBeans ���;�����(���%thaijavaapp -� ���'���5���(��Deploy to Google App

���!�,�����-��#��9��%��� �Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan

Page 10: Google App Engine Using NetBeans (in Thai)

10

Engine �����1�����deploy ����-�����-��#"� �#�username -���password ����Google App

Engine ������12. �#'(����-��#��%����%��#����&�� ����#��(�Browser �!'(�*��(�https://appengine.goog le.com/ 3+(�"�-�%�)���!?&%������(�1.9��� ����%�(�#������������&��(�(1) �����������-��#�3+(�"�*% )���!?&%������(�1.10

�������1.9����� # ��current versions )��My Applications

�������1.10���������������� ���$��Google App Engine

1.4 ��������� ����� �Servlet � ���!� ������ �Google App Engine� �

�������"���1����!�,�����-��#�Java Servlet �!'(�-�%������7""$���-� ���%������Google App

Engine �%�#���������!�,�����-��#%���

���!�,�����-��#��9��%��� �Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan

Page 11: Google App Engine Using NetBeans (in Thai)

11

1. ��'���� ��2���Projects -� ����;�����(���%��thaijavaapp"�������'���5���(��New > Servlet...

2. ��*%���9���New Servlet �5���%�2��Class Name ��1��TimerServlet -���Package ��1��timer

-� ��%�Finish

3. ������$����-��#�TimerServlet.java �� ��1�*�%���Listing �(�1.1

4. �5����������-��#�!'(��%������localhost -� ��5�����deploy ���Google App Engine -� ��%���������-��#�(�http://thaijavaapp.appspot.com/TimerServlet "�*% )���!?&%������(�1.11

�������1.11���������������� ����TimerServlet $��Google App Engine

Listing �(� 1.1 ����-��#� TimerServlet.java

package timer;

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, ""));

���!�,�����-��#��9��%��� �Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan

Page 12: Google App Engine Using NetBeans (in Thai)

12

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>");

out.close(); }

// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to editthe 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>}

1.5 ��������� �����!� ����" ���� �Google Account� �

Google App Engine #�$%�5���(��API �!'(��� ���!�,����#�� ������ �Application�2��@����Google

*% ���# +���'(�#�2�����Google Account �������"���1������ �5���(����Google API ��������User -��UserService �!'(���%�2�����Google Account�%�"�#������%���

���!�,�����-��#��9��%��� �Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan

Page 13: Google App Engine Using NetBeans (in Thai)

13

1. ��'���� ��2���Projects -� ����;�����(���%��thaijavaapp"�������'���5���(��New > Servlet...

2. ��*%���9���New Servlet �5���%�2��Class Name ��1��GoogleTimerServlet -���Package ��1�timer -� ��%�Finish

3. ������$����-��#�GoogleTimerServlet.java �� ��1�*�%���Listing �(�1.2

4. �5�����deploy ���Google App Engine -� ��%���������-��#�(http://thaijavaapp.appspot.com/GoogleTimerServlet "�*% )���!?&%������(�1.12�-���1.13

�������1.12���������������� ����GoogleTimerServlet $��Google App Engine

�������1.13���������������� ����TimerServlet ����!�����signin

Listing �(� 1.2 �� ���-��#� 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;

���!�,�����-��#��9��%��� �Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan

Page 14: Google App Engine Using NetBeans (in Thai)

14

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) + "\">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 editthe 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

���!�,�����-��#��9��%��� �Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan

Page 15: Google App Engine Using NetBeans (in Thai)

15

* @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>}

���!�,�����-��#��9��%��� �Google App Engine Thanachart Numnonda / Thanisa Kruawaisayawan

Page 16: Google App Engine Using NetBeans (in Thai)

16

Exercise 2 �������Mail API ���URLFetch ���GAE

-��./���%���1������2������� �Services ����Google App Engine �%�"�!�,�����-��#�+�#�������-��#�'��EmailSenderServlet.java �!'(��� �Mail API ������2��E-mail "���Google Account ���)� �� �(Login �� �#��-�����-��#�DictionaryServlet.java �!'(��� �URL Fetch API ����������url ���Dictionary Service

2.1 ��������� �������"��� �Email� �

Google App Engine ��#�� �("������� �Mail API �!'(��2��Mail *% ��%����(�"��� �User Account

����Gmail ������2�����-��#�"�#����2���'��MailSender.html �5�����-��6��&#�2��-���-��EmailSenderServlet.java 3+(���1����-��#�Servlet �(�� ������2��mail "���Google Account

2.1.1 ���!�,�����-��#� MailSender.html

���-��#�MailSender.html ��1���9��!"�(�� -�%�6��&#�5������� )� �� �A���E-mail, Subject -��� ����#�("��2���%�#���������!�,��%���

1. ��'���� ��2���Projects -� ����;�����(���%�thaijavaapp "�������'���5���(��New > Other…

2. ��*%���9���New File �� ��'���Categories �(�'(��Web ��'���File Types: ��1��HTML -� ��%�Next

3. �5���%�HTML File Name: ��1��MailSender.html -� ��%�Finish

4. �����source code ���*6�&�findBook.html ��#�Listing �(�2.1��%������#�� �("�����icon ����4�HTML Forms �(���2���� ��2���Palette �!'(���#�� �� �������-��#*% �2���+�

Listing 2.1 ���-��#� MailSender.html

<html> <head> <title></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

Page 17: Google App Engine Using NetBeans (in Thai)

17

2.1.2 ���!�,�����-��#� EmailSenderServlet.java

���-��#�EmailSenderServlet "��2���2�!���#�����&�(�2�#�"��*6�&�MailSender.html�%�)� �� "�� ���5�����signin �%��� �Google Account �2����%�"�#���������!�,��%���

1. ��'���� ��2���Projects -� ����;�����(���%��thaijavaapp"�������'���5���(��New > Servlet...

2. ��*%���9���New Servlet �5���%�2��Class Name ��1��EmailSenderServlet -���Package ��1�services -� ��%�Finish

3. ������$����-��#�EmailSenderServlet.java �� ��1�*�%���Listing �(�2.2

4. �5�����deploy ���Google App Engine -� ��%���������-��#�(http://thaijavaapp.appspot.com/MailSender.html "�*% -��6��&#%������(�2.1�

5. �%����2��E-mail -� ����"����2�)� ���*% ���"���Google Account ��'�*#2

�������2.1���������������� ����MailSender.html $��Google App Engine

Listing �(� 2.2 �� ���-��#� GoogleTimerServlet.java

package services;

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;

����� �Mail API -���URLFetch ���GAE Thanachart Numnonda / Thanisa Kruawaisayawan

Page 18: Google App Engine Using NetBeans (in Thai)

18

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>"); 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();

}}

����� �Mail API -���URLFetch ���GAE Thanachart Numnonda / Thanisa Kruawaisayawan

Page 19: Google App Engine Using NetBeans (in Thai)

19

2.2 ��������� �����!� #��$�#���$���% �#��� �

�������"���1����!�,�����-��#�!'(��� ������ ������#�#������5�"��Dictionary Service 3+(���1��RESTful Web Services �(���2�(��http://services.aonaware.com/DictService/DictService.asmx -��"�-�%�)���!?&������Servlet -�2��'(��"���Google App Engine #� �"5���%������("������� �URL �%�%�����%��������-��#�"������� �URL Fetch API �!'(�%+�� �#��"���web site %����2��#�-�%�)�

���-��#��-��./���%�#����2���'��WordSearch.html %��-�%����Listing �(�-�����-��#DisctonaryServlet.java %��-�%����Listing �(�3+(����-��#�"�#���������!�,����#'��������-��#����2��Email -��"�*% )��!?&%�������2��������(�2.2�-���2.3

Listing 2.3 ���-��#� WordSearch.html

<html> <head> <title></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.4 �� ���-��#� 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();

����� �Mail API -���URLFetch ���GAE Thanachart Numnonda / Thanisa Kruawaisayawan

Page 20: Google App Engine Using NetBeans (in Thai)

20

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>");

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(); }

}

�������2.2�����������'���������������Google

����� �Mail API -���URLFetch ���GAE Thanachart Numnonda / Thanisa Kruawaisayawan

Page 21: Google App Engine Using NetBeans (in Thai)

21

�������2.3��������!����'��������$��Google App Engine

����� �Mail API -���URLFetch ���GAE Thanachart Numnonda / Thanisa Kruawaisayawan

Page 22: Google App Engine Using NetBeans (in Thai)

22

Exercise 3 �������Datastore % �GAE ��������JPA

��*+������'��,-�.�������� ���!�,�����-��#��9��%��� �Google App Engine� Java Persistence API

�����9�� �#���������-��#�Web Application �("�� �����������)� �� "5����#����1���'(���2��� ��������'(��"��)� �� "�� �������� ���-��#"���Web Server "5�����������'(��"+���"�5��� ��������� ���-��#-�2�������� �Web Server �(*#235�����-���Web Server �$����'(��"�� ����#�� ��%�2����� �#���(��"���"�����2�����'(��-#2�2������@���'(��*% �Google App Engine #��*������"�%����Infrastructure �!'(��5��� ���!�,�����-��#*#2� �������������"�%����7B�����2������%���#�� �("�"�%���� �#��*% �%�)2���API �(����Google

�5���%*� ��

Google App Engine ������$�����������-��#���"�%���C��� �#���%�����5���%#���C��*� ���-���'��Java Data Objects (JDO) -���Java Persistence API (JPA) 3+(�������-���"��� -!��6��&#����DataNucleus Access �����9�� �#����?�"��� ��?-���Object Database 3+(�-���2��"���RDBMS ��(�@*��%�����)� !�,�����-��#�(�� �RDBMS ��""�� ������-����%�����9�� �#����#2�!'(��� !�,���Google Web

Application ��1�*�*% �2���+�

-��./���%�"���1������2�������9�� �#��)� �� �#��#��9��!"�(Guestbook) �%��� �JPA �%����-��#"��5������ ���Entity �(�'(��GuestList -� ��������-��#�!'(���9�-��-�%�� �#�����)� �� �#��#��%��� �Google

Account ������signin

3.1 ���������� �Persistence Unit� �

Persistence Unit ��1�����5���%�� �JPA �� *% �2��Entity Class "� ������$#% ���Entity Manager ����%�-����1�����5���%�Data Source -���Provider �("��� ����Entity �����-��#�NetBeans Plugin �5�����Google App Engine *% �� ���Provider �5������DataNucleus *� �-�2����� �������NetBeans 6.8 ���#�7B�����2�%�����-��./���%�"��� ���Persistence Unit"��*6�&�persistence.xml �%�����3+(�#������%���

1. ��'���� ��2���Projects -� ����;�����(���%��thaijavaapp"�������'���5���(��New > Other...

2. ��*%���9���New File �� ��'���Categories �(�'(��Persistence ��'���File Types: ��1��Persistence

Unit -� ��%�Next

3. �5���%�Persistence Unit Name: ��1��thaijavaappPU ��#�(���*�

����� �Datastore ���GAE �%��� ��JPA Thanachart Numnonda / Thanisa Kruawaisayawan

Page 23: Google App Engine Using NetBeans (in Thai)

23

4. �2���2��Persistence Provider: �� ��'����1��DataNucleus -����'���2��Data Source: ��1���2��%@�9*% ��!������"������5���(��XML �%����-� ��%�Finish

5. ������$��sourcecode ����persistence.xml �(���2�����%�thaijavaapp > Configuration Files �� ��1�%���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/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/> <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 "���1��Entity Class �(������*�% ��6D�%&�2��@�'�� id ��1�� �#�����%String -����1��PrimaryKey (id)

� author ��1�� �#�����%com.google.appengine.api.users.User

� date ��1�� �#�����%java.util.Date

� content ��1�� �#�����%String

���-��#�#���������!�,��%����

1. ��'���� ��2���Projects -� ����;�����(���%��thaijavaapp "�������'���5���(��New > Other...

2. ��*%���9���New File �� ��'���Categories �(�'(��Persistence ��'���File Types: ��1��Entity Class

-� ��%�Next

3. ��*%���9���New Entity Class �5���%�Class Name: ��1��GuestList �'(��Package: ��1��entity

-���Primary Key Type: ��1��String %������(�3.1�-� ��%�Finish

����� �Datastore ���GAE �%��� ��JPA Thanachart Numnonda / Thanisa Kruawaisayawan

Page 24: Google App Engine Using NetBeans (in Thai)

24

�������3.1������ ���Entity Class

4. ���� ��2���Editor �� -� *���Source code ���*6�&�GuestList.java �%���%�5���(�@GeneratedValue(strategy = GenerationType.AUTO)����

5. �!�(#��attribute 4����������%���@BasicUser author;String content;Date visitDate;

6. ���-��#"�#� �)�%!��%��'(��"�����*#2#�5���(��import �5����������(��(��� ���� ��'���5���(��FixImports

7. �������������Date ���-��#"���'��� �)�%!��%�2�� ���5���%�annotation �(�'(��@Temporal �� �!�(#�source code �2���5���(��Date visitDate; %���

@Temporal(javax.persistence.TemporalType.DATE) Date visitDate;

8. �5�����Fix Imports �������!'(��� ���5���(��import �5����������Temporal

9. �!�(#�source code �5������constructor ��������GuestList %���

public GuestList() { }

public GuestList(User author, String content, Date date) {

����� �Datastore ���GAE �%��� ��JPA Thanachart Numnonda / Thanisa Kruawaisayawan

Page 25: Google App Engine Using NetBeans (in Thai)

25

this.id = author.getEmail(); this.author = author; this.content = content; this.visitDate = date; }

10.�5�����encapsulate attribute (�5���%�attribute �� ��1��private -����� ���#?�%�getter -���setter)

�%�������;����4������ ��2���editor ����source code -� ���'���Refactor > Encapsulate Field..

11. ��*%���9���Encapsulate Fields �� ��'���� ���Getter -���Setter �5������Field�2��@%������(�3.2

-� ��%�$:#�Refactor

��������3.2 ����� �Field ����'�����Encapsulate

12.���-��#"��!�(#�source code �%��5���%�� �field �2��@�#�access modifier ��1��private -� ��!�(#�#?�%�setter -���getter �%�"�#�sourcecode %���Listing �(�3.2

Listing �(� 3.2 � sourcecode �5��������-��#� 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;

����� �Datastore ���GAE �%��� ��JPA Thanachart Numnonda / Thanisa Kruawaisayawan

Page 26: Google App Engine Using NetBeans (in Thai)

26

@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; 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() {

����� �Datastore ���GAE �%��� ��JPA Thanachart Numnonda / Thanisa Kruawaisayawan

Page 27: Google App Engine Using NetBeans (in Thai)

27

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 */ 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 "���%�2�����Datastore �%��� ����"9����%�EntityManager �%��� ��#�"���EntityManagerFactory ���-��#�EMF.java ��1����-��#�(!�,���+�#��!'(��� ������"9�%����2����%�#���������!�,�����-��#%���

1. ��'���� ��2���Projects -� ����;�����(���%��thaijavaapp"�������'���5���(��New > Java Class...

2. ��*%���9���New Java Class �5���%�2��Class Name ��1��EMF -���Package ��1��entity -� ��%Finish

3. ������$����-��#�EMF.java �� ��1�*�%���Listing �(�3.3

����� �Datastore ���GAE �%��� ��JPA Thanachart Numnonda / Thanisa Kruawaisayawan

Page 28: Google App Engine Using NetBeans (in Thai)

28

Listing �(� 3.3 � sourcecode �5��������-��#� 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; }}

3.4 ��������� ����� �SignGuestListServlet � ���!� ������ �Google App Engine� �

�������"���1����!�,�����-��#�Java Servlet �!'(���9�� �#�����)� �� �����Datastore �(�'(�GuestList �%�#���������!�,�����-��#%���

1. ��'���� ��2���Projects -� ����;�����(���%��thaijavaapp"�������'���5���(��New > Servlet...

2. ��*%���9���New Servlet �5���%�2��Class Name ��1��SignGuestListServlet -���Package ��1�timer -� ��%�Finish

3. ������$����-��#�SignGuestListServlet.java �� ��1�*�%���Listing �(�3.4

4. �5����������-��#�!'(��%������localhost -� ��5�����deploy ���Google App Engine -� ��%���������-��#�(�http://thaijavaapp.appspot.com/SignGuestListServlet "�*% )���!?&%������(3.3

�������3.3���������������� ��� SignGuestListServlet $��Google App Engine

����� �Datastore ���GAE �%��� ��JPA Thanachart Numnonda / Thanisa Kruawaisayawan

Page 29: Google App Engine Using NetBeans (in Thai)

29

Listing �(� 3.4 ����-��#� SignGuestListServlet.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 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;

/** * * @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>");

����� �Datastore ���GAE �%��� ��JPA Thanachart Numnonda / Thanisa Kruawaisayawan

Page 30: Google App Engine Using NetBeans (in Thai)

30

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 editthe 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>}

3.5 ��������� �����!� ��������� &���� �GuestList� �

�������"���1�����������-��#�Servlet �!'(��� �5���(��JPA �����-�%���������%� �#�����datastore �(�'(��GuestList�%�"�#������%���

1. ��'���� ��2���Projects -� ����;�����(���%��thaijavaapp"�������'���5���(��New > Servlet...

����� �Datastore ���GAE �%��� ��JPA Thanachart Numnonda / Thanisa Kruawaisayawan

Page 31: Google App Engine Using NetBeans (in Thai)

31

2. ��*%���9���New Servlet �5���%�2��Class Name ��1��GuestDisplayServlet -���Package ��1�timer -� ��%�Finish

3. ������$����-��#�GuestDisplayServlet.java �� ��1�*�%���Listing �(�3.5

4. �5�����deploy ���Google App Engine -� ��%���������-��#�(http://thaijavaapp.appspot.com/GusetDisplayServlet "�*% )���!?&%�������2��������(�3.4�

�������3.4���������������� ����GusetDisplayServlet $��Google App Engine

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();

����� �Datastore ���GAE �%��� ��JPA Thanachart Numnonda / Thanisa Kruawaisayawan

Page 32: Google App Engine Using NetBeans (in Thai)

32

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>"); } 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";

����� �Datastore ���GAE �%��� ��JPA Thanachart Numnonda / Thanisa Kruawaisayawan

Page 33: Google App Engine Using NetBeans (in Thai)

33

}// </editor-fold>}

����� �Datastore ���GAE �%��� ��JPA Thanachart Numnonda / Thanisa Kruawaisayawan

Page 34: Google App Engine Using NetBeans (in Thai)

34

Exercise 4 ��������� ����������Google Web ToolkitFramework

��*+������'��,-�.�������� ���!�,�����-��#��9��%��� �Google App Engine

Google Web Toolkit (GWT)��1��Web Application Framework �(!�,���+�#��%��Google �!'(��� ���!�,�����-��#��#�� �������-��#�Rich Internet Applications (RIAs) -���AJAX �%�*#2� ���������-��#4�8��JavaScript-�2��#�� �("��� 4�8��Java �����!�,��*% �%����

-��./���%���1�����5����-��#�NetBeans �!'(�#�!�,�����-��#�%��� �GWT Frameworks -� ��%���!�,�����-��#��'��� ��!'(��%�������5�������Google App Engine

4.1 ����������� �GWT � � �����'� ��% ��� �NetBeans � �

�������"���1������%����Google Web Toolkit -�����;����������-��#�NetBeans 6.8 �!'(��� �����!�,�����-��#��9��%��� �Google Web Toolkit Framework �%�#������%���

1. �5����%���&���%�Google Web Toolkit �(��http://code.google.com/webtoolkit/downloads.html

2. �5�����unzip*6�&�(%���&���%��%��5���%*� ��*%��9����(�(��#���#������2��c:\gwt-2.0.4

3. ������-��#�NetBeans -� ���'���#���Tools > Plugins

4. ��*%���9���Plugins ��'��-���Available Plugins -� ���'���GWT4NB %������(�4.1

�������4.1�����*���GWT2NB Plugin

���!�,�����-��#�%��� �Google Web Toolkit Framework Thanachart Numnonda / Thanisa Kruawaisayawan

Page 35: Google App Engine Using NetBeans (in Thai)

35

5. �%�$:#�Install ���-��#"��5������%����5���(�-���Library ������2��!�,���GWT Framework

4.2 ���������� �Web Application Project� �

�������"���1�������-��#�Web Application �%��� �GWT Framework 3+(�"�������24���� Google App Engine�%������ ���Project ��#2�+�#��3+(�#������%���

1. ��'���#���File => New Project..

2. ��*%���9���New Project �� ��'���Categories ��1��Java Web -����'���Project ��1��Web

Application -� ��%�Next

3. �5���%�Project Name ��1��thaigwtapp -� ���'���Project Location ��1��Director �(���� �����"���9�*6�&*� ��%�Next

4. "�������'���Server ��1��Google App Engine -� ��%�Next

5. ��'���Framework ��1��Google Web Toolkit -���5���%�GWT Installation Folder: ��#*%��9����(�(��%����GWT *� ���5���%�2��GWT Module: ��1��org.thaijavadev.Main%������(�4.2�-� ��%�Finish

�������4.2 ����� �GWT Framework

6. ���-��#��NetBeans "��� ��*6�&�2��@��#������ ���%������(�4.3

7. �5�����Deploy ����"9�������Google App Engine �%����*��sign up �� ��account �������(

���!�,�����-��#�%��� �Google Web Toolkit Framework Thanachart Numnonda / Thanisa Kruawaisayawan

Page 36: Google App Engine Using NetBeans (in Thai)

36

Google App Engine�(�https://appengine.google.com/ -� ��%�$:#�Create an Application

8. �5���%�2��Application Identifier: ��1��thaigwtapp -���Application Title: ��1��GWT

Application -� ��%�$:#�Save

9. �����-��#�NetBeans ���;�����(���%thaijgwtapp -� ���'���5���(��Deploy to Google App

Engine �����1�����deploy ����-�����-��#"� �#�username -���password ����Google App

Engine ������10. �#'(����-��#��%����%��#����&�� ����#��(�Browser �!'(�*��(�https://appengine.goog le.com/ �� �%�(�#������������&��(�(1) �����������-��#��thaigwtapp 3+(�"�*% )���!?&%������(�4.4

�������4.3�����#�'������� ����Web Application

�������4.4���������������� ����thaigwtapp

���!�,�����-��#�%��� �Google Web Toolkit Framework Thanachart Numnonda / Thanisa Kruawaisayawan

Page 37: Google App Engine Using NetBeans (in Thai)

37

4.3 �#���������� ����� �Google Web Toolkit� �

���-��#�5������Google Web Toolkit "�������*6�&�2��@��#�2���(�5���B%���� Module descriptor� Public resources� Client-side code

���"�����������#�� �("��������-��#�2���Server-side code �!�(#���#������(� �����"�!�,���2���Back-end services

���-��#��9��������2���"�#���-��#���2���2��@%���

� Module Descriptor �'�*6�&�Main.gwt.xml 3+(�"�#�5���(��(�5���B����$%�'��<inherits> �(��1��5���(���#'���5���(��import ��4�8�"����-���5���(��<entry-point> �!'(����$�'(������(��1��EntryPoint �%�#�5���(�%���

<?xml version="1.0" encoding="UTF-8"?><module>

<inherits name="com.google.gwt.user.User"/><entry-point class="org.thaijavadev.client.MainEntryPoint"/>

</module>

� Public Resources �'�*6�&�2��@�("� �������� ��(�*���2�*6�&�HTML, *6�&�CSS ��'��*6�&���4�!��������2����'�*6�&�welcomeGWT.html %��-�%����Listing �(�4.1�3+(�"�#�5���(��<script> �!'(����$*6�&JavaScript �'(��� ������-��#����-��#�JavaScript "� ���� ��#�"�����-��#�Java to JavaScript

Compiler �%������#���"�����-��#4�8�"����(���!�,���+�

Listing �(� 4.1 �� ���-��#� welcomeGWT.html

<html> <head> <meta name='gwt:module' content='org.thaijavadev.Main=org.thaijavadev.Main'> <title>Main</title> </head> <body> <script language="javascript" src="org.thaijavadev.Main/org.thaijavadev.Main.nocache.js"></script> </body>

</html>

� Client-side code �'����-��#�MainEntryPoint.java %��-�%����Listing �(�4.2�3+(����-��#4�8�Java �(!�,���+�-� � ��-����1����-��#�JavaScript ���-��#�"���1����!�,���2����%�2����)� �� (UI; User Interface) �(�� �5���(��API ����Google Web Toolkit -�2#���8�����!�,�����-��#��#'���5���(�-���Swing

���!�,�����-��#�%��� �Google Web Toolkit Framework Thanachart Numnonda / Thanisa Kruawaisayawan

Page 38: Google App Engine Using NetBeans (in Thai)

38

Listing �(� 4.2 ����-��#� MainEntryPoint.java

package org.thaijavadev.client;

import com.google.gwt.core.client.EntryPoint;import com.google.gwt.user.client.ui.Button;import com.google.gwt.user.client.ui.Label;import com.google.gwt.user.client.ui.RootPanel;import com.google.gwt.event.dom.client.ClickEvent;import com.google.gwt.event.dom.client.ClickHandler;

public class MainEntryPoint implements EntryPoint { /** * Creates a new instance of MainEntryPoint */ public MainEntryPoint() { }

/** * The entry point method, called automatically by loading a module * that declares an implementing class as an entry-point */ public void onModuleLoad() { final Label label = new Label("Hello, GWT!!!"); final Button button = new Button("Click me!"); button.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { label.setVisible(!label.isVisible()); } });

RootPanel.get().add(button); RootPanel.get().add(label); }}

4.4 ��������� ����� �Client-Side Code� �

�������"���1����!�,�����-��#�2����%�2����)� �� ��������2����� ��1�*�%������(�4.5�-� ��5���%�2��#'(�)� �� �%�$:#�Login "�-�%��Dialog Box �+�#��%� ��password �������5��2��secret "�*% )���!?&%������(4.6�-�2 ���1��2��'(�"�*% %������(�4.7

�����#�� !�,�����-��#�*% �%����������$��source code ������-��#�MainEntryPoint.java

���2������#?�%onModuleLoad() �� ��1�*���#�Listing �(�4.3�-� ���%������-��#������Google AppEngine

���!�,�����-��#�%��� �Google Web Toolkit Framework Thanachart Numnonda / Thanisa Kruawaisayawan

Page 39: Google App Engine Using NetBeans (in Thai)

39

�������4.5�#����� �����$��'()'������ �����"$

�������4.6�% �/�"��$�"�� # ����"�����#��"!

�������4.7 % �/�"��$�"�� # ����"������� ��

Listing �(� 4.3 � sourcecode ����#?�%� onModuleLoad() �(������$���#2

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) {

���!�,�����-��#�%��� �Google Web Toolkit Framework Thanachart Numnonda / Thanisa Kruawaisayawan

Page 40: Google App Engine Using NetBeans (in Thai)

40

if ("secret".equals(password.getText())) { Window.alert("Welcome " + username.getText()); } else { Window.alert("Invalid authentication"); } } }); }

���"��������#�� �("������StyleSheet ���������-��#��9����!'(��� #6���&�����-�%��2����%�2����)� �� %������(�4.8���#������%�����

�������4.8�#����� �����$��'()'�������()'�Cascade Style Sheet

1. ��'���� ��2���Projects -� ����;�����(���%��thaigwtapp"�������'���5���(��New > Other...

2. ��*%���9���New File �� ��'���Categories �(�'(��Web ��'���File Types: ��1��Cascade Style

Sheet -� ��%�Next

3. �5���%�2��CSS File Name: ��1��Main-� ��%�Finish

4. �!�(#���#�sourcecode ���*6�&�Main.css �� ��1�%���Listing �(�4.4

5. �!�(#�5���(��<link> %���2�*����*6�&�welcomeGWT.html <head> ... <link rel="stylesheet" href="Main.css"/> .... </head>

6. ���� ��2���Projects ��'��*6�&�Main.gwt.xml 4���� ���%�thaigwtapp > Source Packages >org.thaijavadev

7. ���� ��2���Editor �� ����-���General -� ��%�$:#�Add �� �StyleSheet Files -� ��5���%�'(�*6�&��1��Main.css %������(

8. �5�����deploy ���-��#�����Google App Engine -� ��%���������-��#��#2

���!�,�����-��#�%��� �Google Web Toolkit Framework Thanachart Numnonda / Thanisa Kruawaisayawan

Page 41: Google App Engine Using NetBeans (in Thai)

41

�������4.9������ ��%&���Cascade Style Sheet (�Main.gwt.xml

Listing �(� 4.4 � sourcecode ������-��#� Main.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

Page 42: Google App Engine Using NetBeans (in Thai)

42

Exercise 5 GWT : Client/Server Communication

��*+������'��,-�.�������� ���!�,�����-��#�%��� �Google Web Toolkit Framework

GWT #��?����("�!�,�����-��#�("���%�2�����2���Client ����Server �'��RPC (Remote

Procedure Call) �%�"�� ��#���!�,�����-��#"����(��1��Interface -���Class �2��@�(��(��� ��

-��./���%���1�����5����-��#�NetBeans �!'(�#�!�,�����-��#GWT-RPC �%�����%����� ��Service �5��������-�%�� ����#-���$2#�(Random Quote Generator) "�����"��%������������-��#���Development Server �2���("���%��������Google App Engine

5.1 �������� �GWT-RPC � �

�������"���1������ �Wizard �����-��#�Netbeans �!'(��� ���Services �5������GWT-RPC �%�#������%���

1. ��'���� ��2���Projects -� ����;�����(���%��thaigwtapp"�������'���5���(��New > Other...

2. ��*%���9���New File �� ��'���Categories �(�'(��Google Web Toolkit ��'���File Types: ��1�GWT RPC Service -� ��%�Next

3. �5���%�2�Service Name: ��1��GWTService -���Subpackage: ��1��sampleservic %������(�5.1

-� ��%�Finish

�������5.1������ ���GWT RPC Service

GWT : Client/Server Communication Thanachart Numnonda / Thanisa Kruawaisayawan

Page 43: Google App Engine Using NetBeans (in Thai)

43

4. ���-��#��NetBeans "��� ��*6�&�(��(��� ������GWT-RPC �+�#��4 *6�&��#������ ��%������(�5.2

�������5.2�%&�����0����GWT RPC Service

5. �%��������� �RPC Service �(����������GWTServiceUsageExample �%����������$��#?�%onModuleLoad() ������-��#�MainEntryPoint.java ��-��./���%�()2��#��%���

public void onModuleLoad() { RootPanel.get().add(new GWTServiceUsageExample());}

6. �������"9��thaigwtapp "�*% )���!?&%������(�5.3

�������5.3����������������������� ����GWTService

5.2 �������� �Random Quote Service � �

�������"���1����������$��GWT-RPC �(!�,���+���!'(��� �Server �2�� ����#-���$2#����#�-�%�������'(���Client �#'(�#��������� �Service �%�"�#������%���

1. ������$����-��#�GWTServiceImpl.java �� ��1�*�%���Listing �(�5.1

2. �����-��#��MainEntryPoint.java �� �5���%��#?�%�+�#���#2��+(��#?�%%���

public static GWTServiceAsync getService() { return GWT.create(GWTService.class); }

GWT : Client/Server Communication Thanachart Numnonda / Thanisa Kruawaisayawan

Page 44: Google App Engine Using NetBeans (in Thai)

44

3. -� �������$��#?�%onModuleLoad() �� ��1�*�%���Listing �(�5.1�3+(�"�� ���5�����import �����2��@�(��(��� ���� ��� ������(�(� ����'���package ��������Timer, Label �� ��1�%������(�5.4

�������5.4�����*���package �����#�Timer �/�Label

4. �������"9��thaigwtapp "�*% )���!?&��1�� ����#�$2#�(���(��-���*���'(��@%������(�5.5

5. �5�����deploy ���Google App Engine -� ��%����������-��#"���url �(�http://thaigwtapp.appspot.com

�������5.5���������������� ����Random Quote Generator

Listing �(� 5.1 �� ���-��#� GWTServiceImpl.java

package org.thaijavadev.server.sampleservice;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;import java.util.ArrayList;import java.util.List;import java.util.Random;import org.thaijavadev.client.sampleservice.GWTService;

public class GWTServiceImpl extends RemoteServiceServlet implements GWTService { private Random randomizer = new Random(); private static final long serialVersionUID = -15020842597334403L;

GWT : Client/Server Communication Thanachart Numnonda / Thanisa Kruawaisayawan

Page 45: Google App Engine Using NetBeans (in Thai)

45

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() �(������$���#2

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) { //display the retrieved quote in the label: quoteText.setText((String) result); } }; getService().myMethod(null, callback); } };

timer.scheduleRepeating(1000); RootPanel.get().add(quoteText); }}

GWT : Client/Server Communication Thanachart Numnonda / Thanisa Kruawaisayawan

Page 46: Google App Engine Using NetBeans (in Thai)

46

Exercise 6 ��������� ����RIA �&���&������Web Services

-��./���%���1������2�����!�,�����-��#�GWT-RPC �%���������� �Web Services ���Dictionary Service �(!�,���+���-��./���%�(�2 �%�-���("�!�,���Traditional Client -���(������ *6�&HTML -�2"�#�!�,�����-��#-���Rich Internet Application �%��� �GWT-RPC

6.1 ����������( ��� �Service � �% ���� ����� �GWT-RPC � �

�������"���1�����!�(#�3��&���������-��#�GWT-RPC �(!�,����-��./���%�()2��#�����+(��#?�%�'(��searchWord ������"�� ��������$�*6�&����#%��#*6�&�'��GWTService.java,

GWTServiceAsync.java -���GWTServiceImpl.java �%�#���������!�,��%���

1. ������$��interface �(�'(��GWTService.java �%��!�(#�5��������#?�%%���

public String searchWord(String s);

2. ������$��interface �(�'(��GWTServiceAsync.java �%��!�(#�5��������#?�%%���

public void searchWord(String s, AsyncCallback<String> callback);

3. ������$��source code ���*6�&�GWTServiceImpl.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

Page 47: Google App Engine Using NetBeans (in Thai)

47

6.2 ��������)���� ����� �MainEntryPoint.java� �

�������"���1����-� *����-��#�MainEntryPoint.java �!'(��� -�%�)���!?&%�������2��������(�-���#'(��%�$:#�Lookup ���-��#�9"�-�%�)���!?&-��Partial Screen Update�%����-������#�#������5��(� ���%�������2��������(��%�#���������!�,��%���

1. ����������$����-��#��MainEntryPoint.java �� ��1�*�%���Listing �(�6.2

2. �������"9��thaigwtapp "�*% )���!?&%�������2��������(�5.5�-���3. �5�����deploy ���Google App Engine -� ��%����������-��#"���url �(�http://thaigwtapp

.appspot.com

Listing �(� 6.2 � sourcecode ������-��#� MainEntryPoint.java

package org.yournamehere.client;

import com.google.gwt.core.client.EntryPoint;import com.google.gwt.core.client.GWT;import com.google.gwt.event.dom.client.ClickEvent;import com.google.gwt.event.dom.client.ClickHandler;import com.google.gwt.user.client.rpc.AsyncCallback;import com.google.gwt.user.client.ui.Button;import com.google.gwt.user.client.ui.HTML;import com.google.gwt.user.client.ui.RootPanel;import com.google.gwt.user.client.ui.InlineLabel;import com.google.gwt.user.client.ui.TextArea;import com.google.gwt.user.client.ui.TextBox;import com.google.gwt.user.client.ui.VerticalPanel;import org.yournamehere.client.sampleservice.GWTService;import org.yournamehere.client.sampleservice.GWTServiceAsync;

public class MainEntryPoint implements EntryPoint {

/** * Creates a new instance of MainEntryPoint */ public MainEntryPoint() { }

/** * The entry point method, called automatically by loading a module * that declares an implementing class as an entry-point */ 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);

���!�,�����-��#�RIA �(������ �Web Services Thanachart Numnonda / Thanisa Kruawaisayawan

Page 48: Google App Engine Using NetBeans (in Thai)

48

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: ta.setHTML((String) result); } };

bn.addClickHandler(new ClickHandler(){ public void onClick(ClickEvent event) { getService().searchWord(text.getText(), callback); } });

}

public static GWTServiceAsync getService() { return GWT.create(GWTService.class); }}

�������6.1���������������� ����SearchWord

���!�,�����-��#�RIA �(������ �Web Services Thanachart Numnonda / Thanisa Kruawaisayawan

Page 49: Google App Engine Using NetBeans (in Thai)

49

�������6.2���������������� ����SearchWord

���!�,�����-��#�RIA �(������ �Web Services Thanachart Numnonda / Thanisa Kruawaisayawan