GWT RPC无法正常工作

时间:2012-05-21 11:06:27

标签: java gwt smartgwt gwt-rpc

我正在我的GWT项目中制作RPC并且它正在运行,但我想以某种方式使用disapper的数据。我使用localhost作为服务器。我在服务器包中有两个类: 防御:

 package org.elsys.salvation.server;


import org.elsys.salvation.client.Defence;
import org.elsys.salvation.client.FunctionalityManager;

public class Defences {

    private ArrayList<Defence> netDefences;
    private ArrayList<Defence> hardDefences;
    private ArrayList<Defence> softDefences;

    public Defences(FunctionalityManager fm){
        netDefences = fm.getNetDefences();
        hardDefences = fm.getHardDefences();
        softDefences = fm.getSoftDefences();
    }

    public ArrayList<Defence> getNetDefences() {
        return netDefences;
    }

    public ArrayList<Defence> getHardDefences() {
        return hardDefences;
    }

    public ArrayList<Defence> getSoftDefences() {
        return softDefences;
    }
}

和DefenceServiceImpl.java:

package org.elsys.salvation.server;

import java.util.ArrayList;

import org.elsys.salvation.client.DefenceService;
import org.elsys.salvation.client.FunctionalityManager;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class DefenceServiceImpl extends RemoteServiceServlet implements DefenceService {

    private Defences defences;

    @Override
    public void saveDefences(FunctionalityManager fm) {
        defences = new Defences(fm);
    }

    @Override
    public void getHardDefences(FunctionalityManager fm) {
        fm.setHardDefences(defences.getHardDefences());
    }

    @Override
    public void getNetDefences(FunctionalityManager fm) {
        fm.setNetDefences(defences.getNetDefences());
    }

    @Override
    public void getSoftDefences(FunctionalityManager fm) {
        fm.setSoftDefences(defences.getSoftDefences());
    }

}

以下是DefenceService接口:

package org.elsys.salvation.client;

import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

@RemoteServiceRelativePath("defences")
public interface DefenceService extends RemoteService {

    void saveDefences(FunctionalityManager fm);
    void getHardDefences(FunctionalityManager fm);
    void getNetDefences(FunctionalityManager fm);
    void getSoftDefences(FunctionalityManager fm);
}

和DefenceServiceAsync:

package org.elsys.salvation.client;

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

public interface DefenceServiceAsync {

    void saveDefences(FunctionalityManager fm, AsyncCallback<Void> callback);

    void getHardDefences(FunctionalityManager fm, AsyncCallback<Void> callback);

    void getNetDefences(FunctionalityManager fm, AsyncCallback<Void> callback);

    void getSoftDefences(FunctionalityManager fm, AsyncCallback<Void> callback);

}

以下是我调用saveDefences方法的代码:

private void addDiploma() {

        final AsyncCallback<Void> callback = new AsyncCallback<Void>() {
            public void onFailure(Throwable caught) {

            }

            @Override
            public void onSuccess(Void result) {
                SC.say("Submited");
            }
        };

        some code...

        Button submitButton = new Button("Submit");
        submitButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                FM.getDiploma(projectNameTextBox, diplomantsNameTextBox,
                        diplomaLeadersListBox, reviewersListBox,
                        specialtiesComboBox, typeComboBox);
                FM.generateDefences();
                defenceSvc.saveDefences(FM,callback);
                RootPanel.get("mainDiv").clear();
                showDefences();
            }
        });

        some more code...
    }

以下是FM和defenceSvc的辩护:

public FunctionalityManager FM = new FunctionalityManager();
private DefenceServiceAsync defenceSvc = GWT.create(DefenceService.class);

这里是我想将保存的数据传回客户端的地方:

protected void showDefence() {  
        FunctionalityManager funcM = new FunctionalityManager();
        final AsyncCallback<Void> callback = new AsyncCallback<Void>() {
            public void onFailure(Throwable caught) {

            }

            @Override
            public void onSuccess(Void result) {
                // TODO Auto-generated method stub  
            }
        };
        defenceSvc.getHardDefences(funcM, callback);  
        defenceSvc.getNetDefences(funcM, callback);  
        defenceSvc.getSoftDefences(funcM, callback);  
        final ListGrid DiplomaGrid = new ListGrid();  
        DiplomaGrid.setWidth(500);  
        DiplomaGrid.setHeight(224);  
        DiplomaGrid.setShowAllRecords(true);  
        DiplomaGrid.setCanEdit(true);  
        DiplomaGrid.setEditEvent(ListGridEditEvent.CLICK);  
        DiplomaGrid.setModalEditing(true);  

        DiplomaData dd= new DiplomaData(funcM);

        ListGridField nameField = new ListGridField("name", "Project Name");  
        ListGridField diplomantsField = new ListGridField("diplomants", "Diplomants");  
        ListGridField leaderField = new ListGridField("leader", "Leader");   
        ListGridField reviewerField = new ListGridField("reviewer", "Reviewer");  
        ListGridField typeField = new ListGridField("type", "Type"); 
        ListGridField dateField = new ListGridField("date", "Date");
        DiplomaGrid.setFields(new ListGridField[] {nameField, diplomantsField, leaderField,reviewerField, typeField, dateField});  
        DiplomaGrid.setData(dd.getRecords());

        RootPanel.get("mainDiv").add(DiplomaGrid);
    }  

web.xml:

<servlet>
    <servlet-name>defenceServiceImpl</servlet-name>
    <servlet-class>org.elsys.salvation.server.DefenceServiceImpl</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>defenceServiceImpl</servlet-name>
    <url-pattern>/salvation/defences</url-pattern>
  </servlet-mapping>

当我在开发模式下运行它时它正在运行但是当我调用showDefence()方法时,我无法检索服务器数据上的序列化。有人能说出问题出在哪里吗?

2 个答案:

答案 0 :(得分:4)

在服务器端,您正在修改FM,但是您不会将其发送回客户端:这将无效。在客户端和服务器之间传递的对象是通过复制(序列化→反序列化),因此在服务器上进行更改只会影响服务器端副本。您无法更新将对象发送到服务器的对象;您正在发送它的副本,然后服务器必须发送另一个副本并应用更改。

换句话说,对于您的代码,将方法的返回类型从void更改为FM,让服务器返回FM传递的参数,并在客户端,在onSuccess中方法,使用结果更新 singleton 对象(在setHardDefences的回调中,使用服务器返回的FM中的hardDefences设置FM hardDefences;并且类似地用于其他防御)。

答案 1 :(得分:0)

我只是尝试了类似的东西。我想使用虚假数据来测试用户界面,因为我还没有真正的数据。我替换了包含静态数据成员的Singleton类。一名成员是有时被写入的名单。

写入操作无效。

使用Debug遍历它,似乎服务器的每个RPC每次都要实例化类。我通过 getInstance 跟踪Singleton,并为每个RPC实例化了类。

Singleton类的单元测试工作正常,但它是本地的,而不是在服务器上。

我认为这是有道理的,因为在Google服务器上,您可能会运行多个应用程序实例。因为每个人都有自己的单身人士,所以不需要保留它。

基于此,我建议每次调用RPC时都会实例化DefenceServiceImpl,因此它总是一个新类,即你可以保存数据。