Google Web Toolkit 和 Google App Engine 综合教程 交互篇
2010-06-08 00:45
633 查看
Google Web Toolkit 和 Google App Engine 综合教程 交互篇
By Kyle Wu http://www.kylewu.net/google-web-toolkit-app-engine-tutorial-communication.html前面几篇教程已经把Google Web Toolkit 和 Google App Engine 两方面的代码完成了很大部分,这篇教程将让Google Web Toolkit 的客户端代码与 Google App Engine 的服务器端代码联合起来,实现客户端和服务器端的交互。
Google Web Toolkit 如何与服务器交互?
Google Web Toolkit 的程序最终会以JavaScript代码的形式在用户的浏览器上运行。所以,如果要与服务器交互,要使用JavaScript支持的方法。Google Web Toolkit 为我们提供了3种方法。远程过程调用 (Remote Procedure Calls, GWT RPC)
如果项目的服务器端使用Java,并且为服务器端的操作都使用了各种接口,那么 GWT RPC是最好的选择。因为我们使用 Google App Engine 作为服务器端,使用Java编码,所以接下来将使用 GWT RPC来完成我们接下来的教程。更详细的有关 Remote Procedure Calls 的介绍,请看这里。
HTTP 取回 JSON
如果项目的服务器端没有使用Java,亦或是已经使用了JSON 或 XML,那么就可以通过HTTP来取得JSON来实现与服务器端的交互。更详细的有关 JSON 的介绍,请看这里。
利用 JSONP 协议
如果你对 mashup 很感兴趣,那么一定不能错过 Google Web Toolkit 提供的这种方法。更详细的有关 JSONP 的介绍,请看这里。
定义 Service Interface
RPC Service 要由一个 继承自 RemoteService 的接口来定义。这里我们在 net.kylewu.myideastorm.client.service 包下面新建一个名为 DBWorkerService 的接口。package net.kylewu.idea.client.service;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
/**
* * The client side stub for the RPC service.
* */
@RemoteServiceRelativePath("myidea")
public interface DBWorkerService extends RemoteService {
// Remove one idea
Boolean delete(Long id);
String getIdeaBySubject(String subject);
// Read from db
String[] getIdeas();
// Add a new idea
String save(String subject, String detail, String progress);
// Update one idea
String update(String id, String subject, String detail, String progress);
}
肯定有人注意到了,这里方法返回的值都是String,为什么不使用我们之前定义过的Idea呢。这里我只能说很抱歉了,我测试过返回Idea对象,但是在运行时会出现 “did you forget to inherit a required module?”的错误,搜索了很久也没有搞定,希望知道的同学联系我,谢谢。
定义服务器端Service实现
服务器端的类要实现刚才写过的 DBWorkerService 接口,在这里实现我们具体的操作。package net.kylewu.idea.server;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import net.kylewu.idea.client.service.DBWorkerService;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
public class DBWorkerServiceImpl extends RemoteServiceServlet implements
DBWorkerService {
private static final long serialVersionUID = 6183858098728558886L;
@Override
public Boolean delete(Long id) {
PersistenceManager pm = PMF.get().getPersistenceManager();
Idea idea = (Idea) pm.getObjectById(Idea.class, id);
pm.deletePersistent(idea);
pm.close();
return true;
}
@SuppressWarnings("unchecked")
@Override
public String[] getIdeas() {
PersistenceManager pm = PMF.get().getPersistenceManager();
String query = "select from " + Idea.class.getName();
List ideas = (List) pm.newQuery(query).execute();
String[] rtn = new String[ideas.size()];
for (int i = 0; i < ideas.size(); i++) {
Idea idea = ideas.get(i);
rtn[i] = idea.toString();
}
return rtn;
}
@Override
public String save(String subject, String detail, String progress) {
Idea idea = new Idea(subject, detail, progress,
progress.compareTo("100%") == 0 ? new SimpleDateFormat("yyyy-mm-dd")
.format(new Date()) : "null");
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
pm.makePersistent(idea);
} finally {
pm.close();
}
String str = getIdeaBySubject(subject);
return str;
}
@Override
public String update(String id, String subject, String detail,
String progress) {
PersistenceManager pm = PMF.get().getPersistenceManager();
Idea idea = (Idea) pm.getObjectById(Idea.class, Long.valueOf(id));
idea.setSubject(subject);
idea.setDetail(detail);
idea.setProgress(progress);
if (progress.compareTo("100%") == 0
&& idea.getDate().compareTo("null") == 0) {
idea.setDate(new SimpleDateFormat("yyyy-mm-dd").format(new Date()));
}
pm.makePersistent(idea);
String rtn = ((Idea) pm.getObjectById(Idea.class, Long.valueOf(id)))
.toString();
pm.close();
return rtn;
}
@SuppressWarnings("unchecked")
@Override
public String getIdeaBySubject(String subject) {
PersistenceManager pm = PMF.get().getPersistenceManager();
Query query = pm.newQuery("select from " + Idea.class.getName()
+ " where subject == subjectParm "
+ "parameters String subjectParm");
List ids = (List) query.execute(subject);
if (ids.isEmpty() == false) {
pm.close();
return ids.get(0).toString();
}
pm.close();
return "";
}
}
如上一篇教程最后部分提到的,这里通过PMF得到PersistenceManager,进而进行数据库的增删改查。
定义 RPC Interface
代码很简单,在我们的DBWorkerService接口中的方法的参数最后添加一个AsyncCallback参数,并且这些方法都是void。package net.kylewu.idea.client.service;
import com.google.gwt.user.client.rpc.AsyncCallback;
/**
* The async counterpart of DBWorker.
*/
public interface DBWorkerServiceAsync {
// Remove one idea
void delete(Long id, AsyncCallback callback);
// Read from db
void getIdeas(AsyncCallback callback);
// Add a new idea
void save(String subject, String summary, String progress, AsyncCallback callback);
// Update one idea
void update(String id, String summary, String subject, String progress, AsyncCallback callback);
void getIdeaBySubject(String subject, AsyncCallback callback);
}
好了,到这里,就可以调用 RPC 接口了。
调用 RPC Interface
重新打开EntryPoint,在类中添加一段如下代码,然后在需要数据库操作的地方添加代码。private DBWorkerServiceAsync dbWorker = GWT.create(DBWorkerService.class);
这里是最后完整的Kylewuidea类。
package net.kylewu.idea.client;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import net.kylewu.idea.client.service.DBWorkerService;
import net.kylewu.idea.client.service.DBWorkerServiceAsync;
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.DialogBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
/**
* Entry point classes define onModuleLoad().
*/
public class Kylewuidea implements EntryPoint {
private final int COL_ID = 0;
private final int COL_SUBJECT = 1;
private final int COL_DETAIL = 2;
private final int COL_PROGRESS = 3;
private final int COL_TIME = 4;
private final int COL_OPERATION = 5;
private FlexTable table = new FlexTable();
private ArrayList subjectList = new ArrayList();
private Map mapStrToInt = new HashMap();
private Map mapIntToStr = new HashMap();
private DBWorkerServiceAsync dbWorker = GWT.create(DBWorkerService.class);
/**
* This is the entry point method.
*/
public void onModuleLoad() {
// Initial all items.
init();
// Add table to html page.
RootPanel.get("ideastorm").add(createBasePanel());
// Initial table.
importFromDatabase();
}
private void init() {
mapStrToInt.put("0%", 0);
mapStrToInt.put("25%", 1);
mapStrToInt.put("50%", 2);
mapStrToInt.put("75%", 3);
mapStrToInt.put("100%", 4);
mapIntToStr.put(0, "0%");
mapIntToStr.put(1, "25%");
mapIntToStr.put(2, "50%");
mapIntToStr.put
相关文章推荐
- Google Web Toolkit 和 Google App Engine 综合教程 启蒙篇
- Google Web Toolkit 和 Google App Engine 综合教程 界面篇
- Google Web Toolkit 和 Google App Engine 综合教程 存储篇
- 个人新作品《云应用开发——Google App Engine & Google Web Toolkit入门指南》
- 有关google的appengine部署服务器的简单教程
- Google App Engine 6步上手教程
- 最新Google App Engine应用申请教程
- 用Google App Engine开发Go应用的简明教程
- [GAE教程]初识 Google App Engine
- google app engine简明教程---Python版
- Google App Engine(GAE)入门教程翻译
- Google App Engine服务申请教程(GAE)
- Google App Engine 的简易教程(转载)
- Django+Python+GoogleAppEngine+HTML/XHTML+CSS = WEB APP
- GWT(google web toolkit)教程(一) 配置
- Web.py Cookbook 简体中文版 - How to use templates on Google App Engine
- 在GAE(Google App Engine)上搭建python2.7的web.py程序
- Google App Engine helloworld 入门教程