2010-02-10 84 views
7

我想解決如何使用GWT RPC將服務器端的域對象發送到客戶端。我編寫了一個非常簡單的用例,代表了我(和其他人)需要做的事情,但目前無法工作。GWT簡單的RPC用例問題:包含的代碼

我已經搜遍了文檔,教程和論壇,但它們要麼顯示字符串被傳遞或提供解釋(當我將它們應用於此)仍然不起作用。

希望有人能向我和其他人解釋爲什麼這段代碼不起作用,以及如何讓它起作用。

謝謝。

以下是錯誤消息。

13:12:54.328 [DEBUG] [org.redboffin.worldhug.Test] Validating newly compiled units 
13:12:54.328 [ERROR] [org.redboffin.worldhug.Test] Errors in 'file:/C:/Documents%20and%20Settings/Darren/workspace/WorldHug/src/org/redboffin/worldhug/client/test/TestService.java' 
13:12:54.343 [ERROR] [org.redboffin.worldhug.Test] Line 14: No source code is available for type org.redboffin.worldhug.server.test.TestObject; did you forget to inherit a required module? 
13:12:54.515 [ERROR] [org.redboffin.worldhug.Test] Errors in 'file:/C:/Documents%20and%20Settings/Darren/workspace/WorldHug/src/org/redboffin/worldhug/client/test/TestServiceAsync.java' 
13:12:54.515 [ERROR] [org.redboffin.worldhug.Test] Line 12: No source code is available for type org.redboffin.worldhug.server.test.TestObject; did you forget to inherit a required module? 
13:12:55.953 [ERROR] [org.redboffin.worldhug.Test] Errors in 'file:/C:/Documents%20and%20Settings/Darren/workspace/WorldHug/src/org/redboffin/worldhug/client/test/TestView.java' 
13:12:55.968 [ERROR] [org.redboffin.worldhug.Test] Line 42: No source code is available for type org.redboffin.worldhug.server.test.TestObject; did you forget to inherit a required module? 
13:12:55.968 [ERROR] [org.redboffin.worldhug.Test] Line 46: No source code is available for type org.redboffin.worldhug.server.test.InnerObject; did you forget to inherit a required module? 
13:12:55.984 [ERROR] [org.redboffin.worldhug.Test] Line 48: No source code is available for type org.redboffin.worldhug.server.test.ListObject; did you forget to inherit a required module? 
13:12:56.765 [INFO] [org.redboffin.worldhug.Test] Module org.redboffin.worldhug.Test has been loaded 

這裏是項目類和文件。

Test.gwt.xml

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.0.0//EN" "http://google-web-toolkit.googlecode.com/svn/tags/2.0.0/distro-source/core/src/gwt-module.dtd"> 
<module> 
    <inherits name="com.google.gwt.user.User" /> 
    <source path="client/test" /> 
    <entry-point class="org.redboffin.worldhug.client.test.Test"></entry-point> 
</module> 

Web.xml中

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE web-app 
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" 
"http://java.sun.com/dtd/web-app_2_3.dtd"> 

<web-app> 

    <!-- Servlets --> 

    <servlet> 
    <servlet-name>testServlet</servlet-name> 
    <servlet-class>org.redboffin.worldhug.server.test.TestServiceImpl</servlet-class> 
    </servlet> 

    <servlet-mapping> 
    <servlet-name>testServlet</servlet-name> 
    <url-pattern>/worldhug/test/testService</url-pattern> 
    </servlet-mapping> 

    <!-- Default page to serve --> 
    <welcome-file-list> 
    <welcome-file>test.html</welcome-file> 
    </welcome-file-list> 

</web-app> 

TestObject.java

package org.redboffin.worldhug.server.test; 

import java.util.ArrayList; 
import java.util.List; 

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

public class TestObject implements IsSerializable { 

    private String testObjectString; 
    private InnerObject innerObject; 
    private List<ListObject> listObjects = new ArrayList<ListObject>(); 

    public TestObject() {} 

    // Getters and setters removed for brevity 

} 

InnerObject.java

package org.redboffin.worldhug.server.test; 

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

public class InnerObject implements IsSerializable { 

    private String innerObjectString; 

    public InnerObject() {} 

     // Getters and setters removed for brevity 

} 

ListObject.java

package org.redboffin.worldhug.server.test; 

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

public class ListObject implements IsSerializable { 

    private String listObjectString; 

    public ListObject() {} 

     // Getters and setters removed for brevity. 

} 

TestService.java

package org.redboffin.worldhug.client.test; 

import org.redboffin.worldhug.server.test.TestObject; 

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

/** 
* The client side stub for the Test Service. 
* @author Darren 
*/ 
@RemoteServiceRelativePath("testService") 
public interface TestService extends RemoteService { 

    TestObject test(); 

} 

TestServiceAsync.java

package org.redboffin.worldhug.client.test; 

import org.redboffin.worldhug.server.test.TestObject; 

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

/** 
* The async counterpart of <code>TestService</code>. 
* @author Darren 
*/ 
public interface TestServiceAsync { 

    void test(AsyncCallback<TestObject> callback); 

} 

TestServiceImpl.java

package org.redboffin.worldhug.server.test; 

import java.util.List; 

import org.redboffin.worldhug.client.test.TestService; 

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

/** 
* The server side implementation of the RPC service. 
* @author Darren 
*/ 
@SuppressWarnings("serial") 
public class TestServiceImpl extends RemoteServiceServlet implements TestService { 

    @Override 
    public TestObject test() { 

     TestObject testObject = new TestObject();  
     testObject.setTestObjectString("Test Object String"); 

     InnerObject innerObject = new InnerObject(); 
     innerObject.setInnerObjectString("Inner Object String"); 

       testObject.setInnerObject(innerObject); 

     List<ListObject> listObjects = testObject.getListObjects(); 

     ListObject listObjectOne = new ListObject(); 
     listObjectOne.setListObjectString("List Object One"); 
     listObjects.add(0, listObjectOne); 

     ListObject listObjectTwo = new ListObject(); 
     listObjectTwo.setListObjectString("List Object Two"); 
     listObjects.add(0, listObjectTwo); 

     ListObject listObjectThree = new ListObject(); 
     listObjectThree.setListObjectString("List Object Three"); 
     listObjects.add(0, listObjectThree); 

     return testObject; 
    } 

} 

TestView.java

package org.redboffin.worldhug.client.test; 

import java.util.ArrayList; 
import java.util.Iterator; 

import org.redboffin.worldhug.server.test.InnerObject; 
import org.redboffin.worldhug.server.test.ListObject; 
import org.redboffin.worldhug.server.test.TestObject; 

import com.google.gwt.core.client.GWT; 
import com.google.gwt.event.dom.client.ClickEvent; 
import com.google.gwt.uibinder.client.UiBinder; 
import com.google.gwt.uibinder.client.UiField; 
import com.google.gwt.uibinder.client.UiHandler; 
import com.google.gwt.user.client.rpc.AsyncCallback; 
import com.google.gwt.user.client.ui.Button; 
import com.google.gwt.user.client.ui.Composite; 
import com.google.gwt.user.client.ui.Label; 
import com.google.gwt.user.client.ui.VerticalPanel; 

public class TestView extends Composite { 

    private static TestViewUiBinder uiBinder = GWT.create(TestViewUiBinder.class); 

    interface TestViewUiBinder extends UiBinder<VerticalPanel, TestView> {} 

    @UiField Label testObjectStringLabel; 
    @UiField Label innerObjectStringLabel; 
    @UiField VerticalPanel listObjectsPanel; 
    @UiField Button button; 
    @UiField Label errorMessageLabel; 

    public TestView(String firstName) { 
     initWidget(uiBinder.createAndBindUi(this)); 
    } 

    @UiHandler("button") 
    void onClick(ClickEvent e) { 

     TestServiceAsync testService = (TestServiceAsync) GWT.create(TestService.class); 

     AsyncCallback<TestObject> callback = new AsyncCallback<TestObject>() { 

      public void onSuccess(TestObject testObject) { 
       testObjectStringLabel.setText(testObject.getTestObjectString()); 
       InnerObject innerObject = testObject.getInnerObject(); 
       innerObjectStringLabel.setText(innerObject.getInnerObjectString()); 
       ArrayList<ListObject> listObjects = (ArrayList<ListObject>) testObject.getListObjects(); 
       Iterator<ListObject> iterator = listObjects.iterator(); 
       while(iterator.hasNext()) { 
        ListObject listObject = (ListObject) iterator.next(); 
        listObjectsPanel.add(new Label(listObject.getListObjectString())); 
       } 
      } 

      public void onFailure(Throwable caught) { 
       errorMessageLabel.setText("Error : "+caught.getMessage()); 
      } 
      }; 

      testService.test(callback); 

    } 

} 

TestView.ui.xml

<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent"> 
<ui:UiBinder 
    xmlns:ui="urn:ui:com.google.gwt.uibinder" 
    xmlns:g="urn:import:com.google.gwt.user.client.ui"> 

    <g:VerticalPanel> 
     <g:Label>Test Object</g:Label> 
     <g:Label ui:field="testObjectStringLabel"></g:Label> 
     <g:VerticalPanel> 
      <g:Label>Inner Object</g:Label> 
      <g:Label ui:field="innerObjectStringLabel"></g:Label> 
     </g:VerticalPanel> 
     <g:VerticalPanel ui:field="listObjectsPanel"> 
      <g:Label>List Objects</g:Label> 
     </g:VerticalPanel> 
     <g:Button ui:field="button">Display Test Object</g:Button> 
     <g:Label ui:field="errorMessageLabel"></g:Label> 
    </g:VerticalPanel> 

</ui:UiBinder> 

感謝您遠讀這篇文章,任何幫助,您可以給我(和其他人)。

+0

Java RPC中的樣板代碼的數量比Java中的其他任何東西都更讓我煩惱。我真的希望,至少在這種情況下,他們會採用Ruby的Convention Over Configuration方法,並讓您放棄可串行化的對象。我實際上已經嘗試了這種方法,每當你到達一個新的虛擬機時都會調用一個arriAt()方法。它確實很漂亮,但是ArriAt方法傾向於將整個客戶端和服務器拉入到每個構建中。但是我有這樣的想法:能夠標記@client或@server方法並有條件地編譯它們... – 2010-10-07 20:53:58

回答

10

您需要標識包含要編譯GWT的源的所有包。

例如

<source path="client/test"/> 
<source path="server/test"/> 

將您的域類不放在服務器包中可能是一個更好的選擇。我們經常做這樣的事情:

<source path="client"/> 
<source path="shared"/> 

其中共享包含在客戶端和服務器之間來回傳遞的DTO。

+0

謝謝克雷格 - 現在完美地工作。 使用'共享'包的好建議。 – Darren 2010-02-10 15:57:43

0

如果使用DTO,則必須在共享文件夾(約定)中插入可傳送對象。如果使用域對象非共享而不是「傳輸」,則可以在服務器文件夾中插入文件夾(例如「域」),但此「類型」不能用於異步調用。道德:如果一個對象被轉移,必須「共享」,否則你可以安全地在服務器文件夾中使用。

+0

我同意分享。但是將類文件插入服務器文件夾是一種錯誤的方法。 – 2012-09-26 02:49:15