Reputation: 435
I'm making RPC in my GWT project and it's running but the data I wanna work with disapper somehow. I am using the localhost as server. I have two classes in the server package: Defences:
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;
}
}
and 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());
}
}
Here are the DefenceService interface:
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);
}
and 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);
}
Here is the code where I am calling the saveDefences method:
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...
}
Here is the defenition of FM and defenceSvc:
public FunctionalityManager FM = new FunctionalityManager();
private DefenceServiceAsync defenceSvc = GWT.create(DefenceService.class);
here is where I want to get saved data back to the client side:
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);
}
the 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>
When I run it in developement mode it's running but when I call the showDefence() method I can't retrieve the serialised on the server data. Can someone tell where is the problem?
Upvotes: 2
Views: 1054
Reputation: 843
I just attempted something similar to this. I wanted to use fake data for testing the UI because I don't have real data, yet. I substituted a Singleton class containing static data members. One member was a List that was written to at times.
The write operation did not work.
Walking through it with Debug it appears that each RPC to the server is instantiating the classes each time. I traced through the getInstance for the Singleton and for each RPC the class was instantiated.
A unit test on the Singleton class works fine but that is local, not on the server.
I believe this makes sense since on a Google server you might have multiple instances of your application running. Since each would have its own Singleton there is no need to keep it around.
Based on this I suggest that DefenceServiceImpl is instantiated each time the RPC is called so it is always a new class, i.e. you can save data.
Upvotes: 0
Reputation: 64541
On the server-side, you're modifying the FM, but yuo don't send it back to the client: that won't work. Object passing between client and server is by copying (serialize→deserialize), so making a change on the server will only impact the server-side copy. You cannot update an object y sending it to the server; you're sending a copy of it, and the server must then send back another copy with the changes applied.
In other words, for your code, change the methods' return type from void
to FM, have the server return the FM passed a argument, and on the client-side, in the onSuccess
methods, update your singleton object with the result (in the callback from setHardDefences
, set the FM's hardDefences
with the hardDefences
from the FM returned by the server; and similarly for the other defences).
Upvotes: 4