一、 定义服务
GWT过程调用大部分在两个类进行。在服务器端,定义一个 RemoteServiceServlet子类 RegisterActionImpl.java(远程服务实现类)。在这个类中,将操作数据库并将值返回给客户机。在客户端,定义一个实现 AsyncCallback接口的类 Register.java(客户端实现类),在这个类中,定义服务器操作完成时客户机页面如何处理数据(或异常)。除了这两个类之外,必须编写一些绑定代码使 GWT-Ext 可以将客户端类和服务器端类绑定在一起 , 绑定代码包含 RegisterAction.java(远程接口)和 RegisterActionAsync.java(远程异步接口)两个不同的接口外加一些客户端代码以及一两个设置。
a. 在 gwtext项目上点击右键,选择 New—Other—Remote Service,创建名为 RegisterAction的远程服务接口。
b. 把 PostgreSQL数据库的 JDBC包 postgresql-8.2-505.jdbc3.jar加入到项目中(其他数据库,加入相应的 JDBC包)。
c. 远程服务的实现类,在 RegisterActionImpl.java中加入如下代码:
Java代码 复制代码
1. /**
2. * @author 七月天
3. *
4. */
5. public class RegisterActionImpl extends RemoteServiceServlet implements RegisterAction {
6.
7. private static final long serialVersionUID = 1L;
8.
9. public void saveData(Map formData) {
10. Connection conn=null;
11. try {
12. Class.forName("org.postgresql.Driver");
13. String connString="jdbc:postgresql://127.0.0.1:5432/gwtext";
14. conn=DriverManager.getConnection(connString,"julycn","julycn");
15. StringBuffer sqlQuery=new StringBuffer("insert into person (username,password,email,phone) ");
16. sqlQuery.append("values(?,?,?,?)");
17. PreparedStatement stmt=conn.prepareStatement(sqlQuery.toString());
18. stmt.setString(1, URLDecoder.decode(formData.get("username").toString(),"UTF-8"));
19. stmt.setString(2, URLDecoder.decode(formData.get("password").toString(),"UTF-8"));
20. stmt.setString(3, URLDecoder.decode(formData.get("email").toString(),"UTF-8"));
21. stmt.setString(4, URLDecoder.decode(formData.get("phone").toString(),"UTF-8"));
22. stmt.execute();
23. } catch (Exception e) {
24. e.printStackTrace();
25. }finally{
26. if(conn!=null){
27. try {
28. conn.close();
29. } catch (SQLException e) {
30. e.printStackTrace();
31. }
32. }
33. }
34.
35. }
36. }
/**
* @author 七月天
*
*/
public class RegisterActionImpl extends RemoteServiceServlet implements RegisterAction {
private static final long serialVersionUID = 1L;
public void saveData(Map formData) {
Connection conn=null;
try {
Class.forName("org.postgresql.Driver");
String connString="jdbc:postgresql://127.0.0.1:5432/gwtext";
conn=DriverManager.getConnection(connString,"julycn","julycn");
StringBuffer sqlQuery=new StringBuffer("insert into person (username,password,email,phone) ");
sqlQuery.append("values(?,?,?,?)");
PreparedStatement stmt=conn.prepareStatement(sqlQuery.toString());
stmt.setString(1, URLDecoder.decode(formData.get("username").toString(),"UTF-8"));
stmt.setString(2, URLDecoder.decode(formData.get("password").toString(),"UTF-8"));
stmt.setString(3, URLDecoder.decode(formData.get("email").toString(),"UTF-8"));
stmt.setString(4, URLDecoder.decode(formData.get("phone").toString(),"UTF-8"));
stmt.execute();
} catch (Exception e) {
e.printStackTrace();
}finally{
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
d. GWT-Ext远程服务的要求很简单,它必须扩展 RemoteServiceServlet并实现一个接口。
二、 绑定代码
a. 要使新程序可用于客户端应用程序,必须定义两个接口。
b. 定义一个远程接口类 RegisterAction.java,代码如下
Java代码 复制代码
1. /**
2. * @author 七月天
3. *
4. */
5. public interface RegisterAction extends RemoteService {
6.
7. public static final String SERVICE_URI = "/RegisterAction";
8.
9. public static class Util {
10.
11. public static RegisterActionAsync getInstance() {
12.
13. RegisterActionAsync instance = (RegisterActionAsync) GWT
14. .create(RegisterAction.class);
15. ServiceDefTarget target = (ServiceDefTarget) instance;
16. target.setServiceEntryPoint(GWT.getModuleBaseURL() + SERVICE_URI);
17. return instance;
18. }
19. }
20.
21. public void saveData(Map formData);
22. }
/**
* @author 七月天
*
*/
public interface RegisterAction extends RemoteService {
public static final String SERVICE_URI = "/RegisterAction";
public static class Util {
public static RegisterActionAsync getInstance() {
RegisterActionAsync instance = (RegisterActionAsync) GWT
.create(RegisterAction.class);
ServiceDefTarget target = (ServiceDefTarget) instance;
target.setServiceEntryPoint(GWT.getModuleBaseURL() + SERVICE_URI);
return instance;
}
}
public void saveData(Map formData);
}
c. 在这里完成的所有操作是获得用于实际的具体类中方法的同一个签名。这里的主要限制是接口必须扩展 com.google.gwt.user.client.rpc.RemoteService;。此外,参数和返回值必须属于 GWT 可以序列化的类型 (见备注 )。
d. 定义远程异步接口 RegisterActionAsync.java ,代码如下:
Java代码 复制代码
1. /**
2. * @author 七月天
3. *
4. */
5. public interface RegisterActionAsync {
6.
7. public void saveData(Map formData, AsyncCallback callback);
8. }
/**
* @author 七月天
*
*/
public interface RegisterActionAsync {
public void saveData(Map formData, AsyncCallback callback);
}
e. 远程异步类的服务接口是从上面描述的远程服务类中派生出来的。两个类必须位于同一个包中,并且该包必须对 GWT-EXT 客户机代码可见。远程异步类中的类名必须是远程服务接口的名称且末尾附加字符串 Async。对于远程服务接口中的每个方法,远程异步类必须有一个返回类型更改为 void 的匹配方法和一个 AsyncCallback 类型的附加参数。客户端代码将使用 AsyncCallback 作用于服务器响应上。
f. 注册服务器代码,将下面的一行加入到 Register.gwt.xml中
Java代码 复制代码
1. <servlet class="com.gwtext.julycn.server.RegisterActionImpl" path="/RegisterAction" />
<servlet class="com.gwtext.julycn.server.RegisterActionImpl" path="/RegisterAction" />
三、 执行客户端调用
a. 完成服务器端操作以后,现在应该让客户机执行过程调用了。在这里基本的想法是慎重地告诉 GWT 系统正在调用的是哪个远程服务。然后将 AsyncCallback 对象发送出去;最后, GWT 将其送回,您可对结果进行操作。修改模型文件 Register.java,代码如下:
Java代码 复制代码
1. /**
2. * @author 七月天
3. *
4. */
5. public class Register implements EntryPoint,AsyncCallback {
6. public void onModuleLoad() {
7. createComponents();
8. }
9.
10. private void createComponents() {
11. final FormPanel frm = new FormPanel();
12. frm.setDraggable(true);
13. frm.setWidth(300);
14. frm.setTitle("用户注册");
15. frm.setPaddings(25);
16.
17. TextField txtUsername = new TextField("用户名", "username");
18. TextField txtPassword = new TextField("密码", "password");
19. TextField txtEmail = new TextField("邮箱", "email");
20. TextField txtPhone = new TextField("电话", "phone");
21.
22. txtUsername.setRegex("^[a-zA-Z]*$");
23. txtUsername.setRegexText("用户名必须为字母!");
24. txtUsername.setAllowBlank(false);
25.
26. txtPassword.setPassword(true);
27. txtPassword.setRegex("^[a-zA-Z]*$");
28. txtPassword.setRegexText("密码必须为字母!");
29. txtPassword.setAllowBlank(false);
30.
31. txtEmail.setVtype(VType.EMAIL);
32. txtEmail.setVtypeText("请输入合法的邮箱地址!");
33. txtEmail.setAllowBlank(false);
34.
35. txtPhone.setRegex("^\\d*$");
36. txtPhone.setRegexText("电话必须为数字!");
37. txtPhone.setAllowBlank(false);
38.
39. frm.add(txtUsername);
40. frm.add(txtPassword);
41. frm.add(txtEmail);
42. frm.add(txtPhone);
43.
44. Panel buttonPanel = new Panel();
45. buttonPanel.setLayout(new HorizontalLayout(10));
46.
47. final AsyncCallback callback=this;
48.
49. Button btnSave = new Button("保存");
50. btnSave.addListener(new ButtonListenerAdapter() {
51. public void onClick(Button button, EventObject e) {
52. if (frm.getForm().isValid()) {
53. RegisterActionAsync action=RegisterAction.Util.getInstance();
54. Map formData=getFormDataAsMap(frm.getForm());
55. action.saveData(formData, callback);
56. } else {
57. MessageBox.alert("错误","请验证输入的信息是否正确!");
58. }
59. }
60. });
61.
62. Button btnClear = new Button("取消");
63. btnClear.addListener(new ButtonListenerAdapter() {
64. public void onClick(Button button, EventObject e) {
65. MessageBox.alert("取消", "注册信息保存失败!");
66. }
67. });
68.
69. buttonPanel.add(btnSave);
70. buttonPanel.add(btnClear);
71.
72. frm.add(buttonPanel);
73.
74. RootPanel.get().add(frm);
75. }
76.
77. public Map getFormDataAsMap(Form form){
78.
79. String formValues=form.getValues();
80. Map formData=new HashMap();
81. String[] nameValuePairs=formValues.split("&");
82.
83. for(int i=0;i<nameValuePairs.length;++i){
84. String[] oneItem=nameValuePairs[i].split("=");
85. formData.put(oneItem[0], oneItem[1]);
86. }
87.
88. return formData;
89. }
90.
91. public void onFailure(Throwable caught) {
92. MessageBox.alert("失败","数据保存失败!");
93. }
94.
95. public void onSuccess(Object result) {
96. MessageBox.alert("成功","数据保存成功!");
97. }
98. }
/**
* @author 七月天
*
*/
public class Register implements EntryPoint,AsyncCallback {
public void onModuleLoad() {
createComponents();
}
private void createComponents() {
final FormPanel frm = new FormPanel();
frm.setDraggable(true);
frm.setWidth(300);
frm.setTitle("用户注册");
frm.setPaddings(25);
TextField txtUsername = new TextField("用户名", "username");
TextField txtPassword = new TextField("密码", "password");
TextField txtEmail = new TextField("邮箱", "email");
TextField txtPhone = new TextField("电话", "phone");
txtUsername.setRegex("^[a-zA-Z]*$");
txtUsername.setRegexText("用户名必须为字母!");
txtUsername.setAllowBlank(false);
txtPassword.setPassword(true);
txtPassword.setRegex("^[a-zA-Z]*$");
txtPassword.setRegexText("密码必须为字母!");
txtPassword.setAllowBlank(false);
txtEmail.setVtype(VType.EMAIL);
txtEmail.setVtypeText("请输入合法的邮箱地址!");
txtEmail.setAllowBlank(false);
txtPhone.setRegex("^\\d*$");
txtPhone.setRegexText("电话必须为数字!");
txtPhone.setAllowBlank(false);
frm.add(txtUsername);
frm.add(txtPassword);
frm.add(txtEmail);
frm.add(txtPhone);
Panel buttonPanel = new Panel();
buttonPanel.setLayout(new HorizontalLayout(10));
final AsyncCallback callback=this;
Button btnSave = new Button("保存");
btnSave.addListener(new ButtonListenerAdapter() {
public void onClick(Button button, EventObject e) {
if (frm.getForm().isValid()) {
RegisterActionAsync action=RegisterAction.Util.getInstance();
Map formData=getFormDataAsMap(frm.getForm());
action.saveData(formData, callback);
} else {
MessageBox.alert("错误","请验证输入的信息是否正确!");
}
}
});
Button btnClear = new Button("取消");
btnClear.addListener(new ButtonListenerAdapter() {
public void onClick(Button button, EventObject e) {
MessageBox.alert("取消", "注册信息保存失败!");
}
});
buttonPanel.add(btnSave);
buttonPanel.add(btnClear);
frm.add(buttonPanel);
RootPanel.get().add(frm);
}
public Map getFormDataAsMap(Form form){
String formValues=form.getValues();
Map formData=new HashMap();
String[] nameValuePairs=formValues.split("&");
for(int i=0;i<nameValuePairs.length;++i){
String[] oneItem=nameValuePairs[i].split("=");
formData.put(oneItem[0], oneItem[1]);
}
return formData;
}
public void onFailure(Throwable caught) {
MessageBox.alert("失败","数据保存失败!");
}
public void onSuccess(Object result) {
MessageBox.alert("成功","数据保存成功!");
}
}
b. AsyncCallback 接口定义了两个方法: onSuccess(Object result) 和 onFailure(Throwable caught)。必须定义一个可以实现这两个方法的类。当执行远程调用时,模型类的实例并将其传递给异步服务方法。最后,服务器端资源完成,然后调用代码中两个方法之一。成功方法的参数是接口和实现中的调用的返回值。
c. 运行一下,看看效果吧! ^o^
备注:
怎样的字段才是可序列化字段?首先,该字段可属于一个实现了 com.google.gwt.user.client.rpc.IsSerializable 的类型,或者具有一个实现了 IsSerializable 的超类。或者,该字段可以是基本类型之一,其中包括 Java 原语,所有原语包装类, Date 和 String 。序列化类型的数组或集合也是序列化的。但是,如果要将一个 Collection 或 List 序列化, GWT 希望您用一个指定实际类型的 Javadoc 注释对其评注,以便编译器可以使其最优化。
分享到:
相关推荐
### Gwt-ext学习笔记之基础篇 #### 一、安装CypalStudio工具 为了能够开始Gwt-ext的学习之旅,首先需要确保开发环境已经搭建好。CypalStudio是一款非常实用的工具,它能帮助开发者更高效地进行GWT项目的开发。 1....
这篇学习笔记将深入探讨Gwt-ext的核心概念、功能以及如何在实际项目中应用。 GWT是由Google开发的一个开源框架,它允许开发者使用Java语言来编写前端Web应用。GWT编译器会将Java代码转换为优化过的JavaScript,以...
标题中的"Gwt-Ext学习笔记之基础篇"指的是关于Gwt-Ext的初级教程,这是一种基于Google Web Toolkit (GWT) 的扩展库,用于构建富互联网应用程序(RIA)。Gwt-Ext提供了丰富的用户界面组件,使得开发者可以利用Java语言...
尤其对于初学者而言,Gwt-Ext不仅简化了复杂的前端开发流程,还提供了丰富的组件和API,使其成为学习和实践RIA开发的理想之选。 #### Gwt-Ext概述 Gwt-Ext的核心优势在于其对GWT和ExtJs的深度融合。GWT作为一套...
GWT-EXT则是基于GWT之上的一套高级用户界面库,它借鉴了ExtJS的设计理念,提供了更为丰富和强大的UI组件集合,使得开发者能够更加轻松地构建复杂的Web应用程序。 #### 二、CypalStudio工具的安装与配置 **步骤一:...
" Gwt-Ext学习笔记之基础篇.doc "、" Gwt-Ext学习笔记之中级篇.doc "、" Gwt-Ext学习笔记之进级篇.doc "这三份文档,按照从基础到进阶的顺序,系统地介绍了EXT-GWT的使用技巧和实践案例。基础篇可能涵盖EXT-GWT的...
GWT-Ext是GWT的一个扩展,它引入了大量桌面级应用的UI组件,如表格、树形视图、按钮、面板等,使得在Web应用中实现复杂布局和功能变得更加便捷。GWT-Ext的代码是用Java编写的,但最终会编译成优化过的JavaScript,...
这个压缩包包含的资源是关于Gwt-Ext的基础、中级和进阶学习资料,适合想要深入理解和应用Gwt-Ext的开发者。 在"基础篇"中,你将学习到以下知识点: 1. **GWT概述**:Google Web Toolkit是一个用于构建高性能、跨...
GWT-Ext是一个基于Google Web Toolkit (GWT...总的来说,GWT-Ext是GWT开发者的一个强大工具,通过它,你可以轻松地构建出具有专业级用户体验的Web应用。深入了解并熟练使用GWT-Ext,将大大提升你的开发效率和产品质量。
- **GWT-Ext 文档**:学习 GWT-Ext 的组件用法和 API。 - **Cypal Studio 文档**:掌握插件的使用技巧,提高开发效率。 通过这个系列的文章,读者将逐步了解 GWT-Ext 的基本结构,学会如何利用 GWT-Ext 开发出...
GWT (Google Web Toolkit) 是一个开源的Java开发框架,用于构建和部署富互联网应用程序...总而言之,这篇博客文章和附带的示例项目为GWT开发者提供了一次深入学习gwt-ext库的机会,有助于提升他们的GWT应用开发技能。
通过对这个文件的学习和理解,开发者可以更好地掌握如何在项目中集成和使用 GWT-Ext-Tree 组件。 总之,GWT-Ext-Tree 是 GWT 平台上构建高效、美观、交互性强的树形界面的重要工具。它的强大功能和灵活性使得开发者...
《GWT-EXT2.0最佳实践教程》源代码打包下载资源主要涵盖了Google Web Toolkit (GWT) 和EXT-JS 2.0的结合使用,提供了丰富的实践案例和示例代码,旨在帮助开发者深入理解和应用这两项技术。GWT是一款强大的JavaScript...
学习 GWT-Ext 需要对 GWT 和 ExtJs 有一定的了解,同时掌握 Java 语言和基本的 Web 开发概念。通过实践和不断学习,开发者可以充分利用 GWT-Ext 的优势,打造出高性能、用户体验优秀的 RIA 应用程序。
GWT-Ext 控件演示 GWT-Ext 控件演示