GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

前篇:GWT - GWT Designer开发Ajax应用 (04)

概要说明:

输入一个ID,从服务器端传递与此ID对应的Contact对象。


1. 新建一个GWT Java Project

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

图1

设置项目名称为“ContactInfo”,点击Next按钮,

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

2

选中Create GWT module,并设定module的名称为“ContactInfo”,Package名称为“com.pnft.ajax”,点击Finish按钮。创建项目的详细过程见GWTDesigner04


2. 创建一个POJO类:Contact

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

3

注意,一定要在com.pnft.ajax.client包中创建。编辑Contact.java代码,使之如下:

package com.pnft.ajax.client;

import com.google.gwt.user.client.rpc.IsSerializable;

public class Contact implements IsSerializable

{

private int id;

private String name;

private String sex;

private int age;

private String email;

private String address;

private String phone;

public Contact()

{

}

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getSex() {

return sex;

}

public void setSex(String sex) {

this.sex = sex;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public String getEmail() {

return email;

}

public void setEmail(String email) {

this.email = email;

}

public String getAddress() {

return address;

}

public void setAddress(String address) {

this.address = address;

}

public String getPhone() {

return phone;

}

public void setPhone(String phone) {

this.phone = phone;

}

}

注意:一定要使其实现IsSerializable接口,否则Contact对象不能正确传递。


3. 创建一个GWT Remote Service,并将其取名为ContactInfoService

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

4

创建Remote Service的详细步骤,请见GWTDesigner04

ContactInfoService中增加一个方法:public Contact getContact(int id);

使得整个ContactInfoService.java代码如下:

public interface ContactInfoService extends RemoteService

{

public Contact getContact(int id);

/**

* Utility class for simplifying access to the instance of async service.

*/

public static class Util {

private static ContactInfoServiceAsync instance;

public static ContactInfoServiceAsync getInstance(){

if (instance == null) {

instance = (ContactInfoServiceAsync) GWT.create(ContactInfoService.class);

ServiceDefTarget target = (ServiceDefTarget) instance;

target.setServiceEntryPoint(GWT.getModuleBaseURL() + "ContactInfoService");

}

return instance;

}

}

}

保存。这会导致在ContactInfoServiceAsync.javaContactInfoServiceImpl.java中增加和这个接口方法相关的的一些代码。


4. GWT Designer中的Design模式下修改ContactInfo.java文件,使其界面如下:

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

5

注意:修改了ButtonTextBoxLabel的相关的css


5. 在步骤4的基础上修改代码,增加OK按钮的消息处理方法,是整个ContactInfo.java代码如下:

public class ContactInfo implements EntryPoint

{

// 创建Widget

private TextBox textBoxID = new TextBox();

private Button buttonOK = new Button();

private Label labelName = new Label("Name:");

private Label labelSex = new Label("Sex:");

private Label labelAge = new Label("Age:");

private Label labelEmail = new Label("Email:");

private Label labelAddress = new Label("Address:");

private Label labelPhone = new Label("Phone:");

private TextBox textBoxName = new TextBox();

private TextBox textBoxSex = new TextBox();

private TextBox textBoxAge = new TextBox();

private TextBox textBoxEmail = new TextBox();

private TextBox textBoxAddress = new TextBox();

private TextBox textBoxPhone = new TextBox();

private Label labelWarning = new Label("");

// 使相关Widget可见或者不可见

private void setVisible(boolean isVisible)

{

labelName.setVisible(isVisible);

labelSex.setVisible(isVisible);

labelAge.setVisible(isVisible);

labelEmail.setVisible(isVisible);

labelAddress.setVisible(isVisible);

labelPhone.setVisible(isVisible);

textBoxName.setVisible(isVisible);

textBoxSex.setVisible(isVisible);

textBoxAge.setVisible(isVisible);

textBoxEmail.setVisible(isVisible);

textBoxAddress.setVisible(isVisible);

textBoxPhone.setVisible(isVisible);

labelWarning.setVisible(!isVisible);

}

public void onModuleLoad()

{

final RootPanel rootPanel = RootPanel.get();

// WidgetrootPanel中的布局,由GWT Designer自动生成

textBoxID = new TextBox();

rootPanel.add(textBoxID, 42, 41);

buttonOK = new Button();

rootPanel.add(buttonOK, 182, 37);

buttonOK.setSize("46px", "27px");

buttonOK.setText("OK");

labelName = new Label("Name:");

rootPanel.add(labelName, 70, 105);

labelSex = new Label("Sex:");

rootPanel.add(labelSex, 80, 130);

labelAge = new Label("Age:");

rootPanel.add(labelAge, 80, 155);

labelEmail = new Label("Email:");

rootPanel.add(labelEmail, 70, 180);

labelAddress = new Label("Address:");

rootPanel.add(labelAddress, 55, 205);

labelPhone = new Label("Phone:");

rootPanel.add(labelPhone, 65, 230);

textBoxName = new TextBox();

rootPanel.add(textBoxName, 135, 100);

textBoxName.setEnabled(false);

textBoxSex = new TextBox();

rootPanel.add(textBoxSex, 135, 125);

textBoxSex.setEnabled(false);

textBoxSex.setWidth("63px");

textBoxAge = new TextBox();

rootPanel.add(textBoxAge, 135, 150);

textBoxAge.setEnabled(false);

textBoxAge.setWidth("63px");

textBoxEmail = new TextBox();

rootPanel.add(textBoxEmail, 135, 175);

textBoxEmail.setEnabled(false);

textBoxEmail.setVisibleLength(30);

textBoxEmail.setWidth("263px");

textBoxAddress = new TextBox();

rootPanel.add(textBoxAddress, 135, 200);

textBoxAddress.setEnabled(false);

textBoxAddress.setVisibleLength(30);

textBoxAddress.setWidth("263px");

textBoxPhone = new TextBox();

rootPanel.add(textBoxPhone, 135, 225);

textBoxPhone.setEnabled(false);

textBoxPhone.setSize("124px", "21px");

labelWarning = new Label("");

rootPanel.add(labelWarning, 40, 78);

labelWarning.setWidth("221px");

// 开始时使相关Widget不可见

setVisible(false);

// 消息响应方法

buttonOK.addClickListener(new ClickListener()

{

public void onClick(final Widget sender)

{

ContactInfoServiceAsync cisa = (ContactInfoServiceAsync)

GWT.create(ContactInfoService.class);

((ServiceDefTarget)cisa).setServiceEntryPoint(GWT.getModuleBaseURL() +

"ContactInfoService");

// 如果textBoxID为空,则将其值设为0,否则转换成对应的数字

Integer aInt = new Integer(0);

if (textBoxID.getText() != "")

{

aInt = new Integer(Integer.parseInt(textBoxID.getText()));

}

cisa.getContact(aInt.intValue(), new AsyncCallback()

{

public void onFailure(Throwable caught)

{

// 失败

Window.alert("Failed to get response form server:/n" +

caught.getMessage());

}

public void onSuccess(Object result)

{

// 成功。有Contact对象返回

Contact contact = (Contact)result;

if(contact != null)

{

// 如果contact不为空,则显示相关Wdiget,并根据返回结果,设置相应的值

setVisible(true);

textBoxName.setText(contact.getName());

textBoxSex.setText(contact.getSex());

textBoxAge.setText((new Integer(contact.getAge())).toString());

textBoxEmail.setText(contact.getEmail());

textBoxAddress.setText(contact.getAddress());

textBoxPhone.setText(contact.getPhone());

}

else

{

// 如果contact为空,则不隐藏相关的Widget,并在labelWarning上显示

// "No person with such an ID!"

setVisible(false);

labelWarning.setText("No person with such an ID!");

textBoxName.setText("");

textBoxSex.setText("");

textBoxAge.setText("");

textBoxEmail.setText("");

textBoxAddress.setText("");

textBoxPhone.setText("");

}

}

});

}

});

}

}


6. 在服务器端实现在ContactInfoServiceImpl.java中定义的getContact方法如下:

@Override

public Contact getContact(int id)

{

Contact contact = new Contact();

if(id == 100)

{

// 假设一下数据是从数据库或其他数据源中得到

contact.setId(100);

contact.setName("玄机逸士");

contact.setSex("");

contact.setAge(30);

contact.setEmail("[email protected]");

contact.setPhone("18968919681");

contact.setAddress("中国北京东城区xx街道xxxxxx房间");

return contact;

}

return null;

}

到此,所有代码的开发工作已经完成。


7. hosted mode运行。

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

6

结果如下:

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

7

输入100,并点击OK按钮,得到

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

8

输入101,点击OK按钮将得到,

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

9

结果正确。


8. 部署。

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

10

部署到D:/Tomcat6/webapps目录下:

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

11

点击OK按钮即可。


9. web mode下的运行结果(启动Tomcat,如果没有启动的话)

- IE6中的结果:

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

12

输入100,点击OK按钮,

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

13

输入101,点击OK按钮,

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

14

结果正确。

- FireFox3中的运行结果:

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

15

输入100,点击OK按钮,

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

16

输入101,点击OK按钮,

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

17

运行结果也正确。但表现形式和IE6有所不同,同时GWT Designer自动产生的css的作用似乎也没有表现出来。


10. 建立数据库表,并插入测试数据。

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

18

利用MySQL Administrator,在数据库andrew中新建一个数据表,各字段信息如上图,它们和Contact.java中的属性一一对应。

新建一个sql文件testdata.sql,其内容如下:

insert into contact(name, sex, age, email, phone, address) values('玄机逸士01', '', 30, '[email protected]', '13823098201', '中国北京市东城区x街道x大厦xx房间');

insert into contact(name, sex, age, email, phone, address) values('玄机逸士02', '', 31, '[email protected]', '13823098202', '中国北京市东城区x街道x大厦xx房间');

……

insert into contact(name, sex, age, email, phone, address) values('玄机逸士60', '', 89, '[email protected]', '13823098260', '中国北京市东城区x街道x大厦xx房间');

60条记录,也就是说他们的ID是从160

用如下方式导入testdata.sql中的数据:

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

19


11. 修改ContactInfoServiceImpl.java,使其从真正意义上链接数据库。代码如下:

public class ContactInfoServiceImpl extends RemoteServiceServlet

implements ContactInfoService

{

private static Statement mysqlStmt;

private Statement getStatement()

{

Connection conn = null;

Statement stmt = null;

try

{

// localhost:3306 mysql服务器地址:mysql服务端口

// andrew 数据库名称

// user=patrick 用户名为patrick

// password=hi 密码为hi

Class.forName("com.mysql.jdbc.Driver");

conn = DriverManager.getConnection(

"jdbc:mysql://localhost:3306/andrew?user=patrick&password=hi");

stmt = conn.createStatement();

}

catch(Exception e)

{

e.printStackTrace();

}

return stmt;

}

// 重载servletinit方法,在这里获取mysqlStmt

@Override

public void init() throws ServletException

{

mysqlStmt = getStatement();

super.init();

}

private ResultSet selectByID(int id)

{

ResultSet rs = null;

try

{

rs = mysqlStmt.executeQuery("select * from Contact where id = '" + id + "'" );

}

catch(Exception ex)

{

ex.printStackTrace();

}

return rs;

}

@Override

public Contact getContact(int id)

{

Contact contact = new Contact();

ResultSet rs = selectByID(id);

try

{

if(rs.next())

{

contact.setName(rs.getString("name"));

contact.setSex(rs.getString("sex"));

contact.setAge(((Integer)rs.getInt("age")).intValue());

contact.setEmail(rs.getString("email"));

contact.setPhone(rs.getString("phone"));

contact.setAddress(rs.getString("address"));

return contact;

}

}

catch(Exception e)

{

e.printStackTrace();

}

return null;

}

}

保存,并重新发布。结果如下:

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

20

输入100,点击OK按钮,得到,

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

21

根据前面数据库表的测试数据知道ID的范围是1~60,因此不存在ID100的情况。

输入为1的情况:

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

22

输入为30的情况:

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

23

输入为60的情况:

GWT - GWT Designer开发Ajax应用 (05) 利用RPC传递对象

24

后篇:GWT - GWT Designer开发Ajax应用 (06) - 常用控件使用