GWT与JDO问题

我刚刚开始玩GWT我很难让GWT + JAVA + JDO + Google AppEngine与DataStore合作。 我试图遵循不同的教程,但没有运气。 例如,我去了这些教程: TUT1 TUT2

我无法弄清楚如何以及为了使这项工作需要做些什么。 请查看我的简单代码并告诉我我需要做什么,以便我可以将其持久保存到数据存储区:

1.地址实体

package com.example.rpccalls.client; import java.io.Serializable; import javax.jdo.annotations.IdGeneratorStrategy; import javax.jdo.annotations.Persistent; import javax.jdo.annotations.PrimaryKey; public class Address implements Serializable{ @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) private int addressID; @Persistent private String address1; @Persistent private String address2; @Persistent private String city; @Persistent private String state; @Persistent private String zip; public Address(){} public Address(String a1, String a2, String city, String state, String zip){ this.address1 = a1; this.address2 = a2; this.city = city; this.state = state; this.zip = zip; } /* Setters and Getters */ } 

2.人员实体

 package com.example.rpccalls.client; import java.io.Serializable; import java.util.ArrayList; import javax.jdo.annotations.IdGeneratorStrategy; import javax.jdo.annotations.PersistenceCapable; import javax.jdo.annotations.Persistent; import javax.jdo.annotations.PrimaryKey; import com.google.appengine.api.datastore.Key; @PersistenceCapable public class Person implements Serializable{ @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) private Key key; @Persistent private String name; @Persistent private int age; @Persistent private char gender; @Persistent ArrayList
addresses; public Person(){} public Person(String name, int age, char gender){ this.name = name; this.age = age; this.gender = gender; } /* Getters and Setters */ }

3. RPCCalls

 package com.example.rpccalls.client; import java.util.ArrayList; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.TextBox; public class RPCCalls implements EntryPoint { private static final String SERVER_ERROR = "An error occurred while attempting to contact the server. Please check your network connection and try again."; private final RPCCallsServiceAsync rpccallService = GWT.create(RPCCallsService.class); TextBox nameTxt = new TextBox(); Button btnSave = getBtnSave(); public void onModuleLoad() { RootPanel.get("inputName").add(nameTxt); RootPanel.get("btnSave").add(btnSave); } private Button getBtnSave(){ Button btnSave = new Button("SAVE"); btnSave.addClickHandler( new ClickHandler(){ public void onClick(ClickEvent event){ saveData2DB(nameTxt.getText()); } } ); return btnSave; } void saveData2DB(String name){ AsyncCallback callback = new AsyncCallback() { public void onFailure(Throwable caught) { Window.alert("WOOOHOOO, ERROR: " + SERVER_ERROR); // TODO: Do something with errors. } public void onSuccess(String result) { Window.alert("Server is saying: ' " + result + "'"); } }; ArrayList
aa = new ArrayList
(); aa.add(new Address("123 sasdf","", "Some City", "AZ", "93923-2321")); aa.add(new Address("23432 asdf", "Appt 34", "Another City", "AZ", "43434-4432")); Person p = new Person(); p.setName(name); p.setAge(23); p.setGender('m'); p.setAddresses(aa); // !!!!!!!!!!!!!!!!!! SERVER CALL !!!!!!!!!!!!!!!!!! rpccallService.saveName(p, callback); // !!!!!!!!!!!!!!!!!! SERVER CALL !!!!!!!!!!!!!!!!!! } }

4. RPCCallsService

 package com.example.rpccalls.client; import com.google.gwt.user.client.rpc.RemoteService; import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; @RemoteServiceRelativePath("calls") public interface RPCCallsService extends RemoteService { String saveName(Person p); } 

5. RPCCallsServiceAsync

 package com.example.rpccalls.client; import com.google.gwt.user.client.rpc.AsyncCallback; public interface RPCCallsServiceAsync { void saveName(Person p, AsyncCallback callback); } 

6. ** RPCCalls.gwt.xml

        

我尝试在这些教程中添加Key类和其他所有内容,但看起来我错过了一些东西。

这是我的错误: 替代文字http://vasura.s3.amazonaws.com/Picture2.png

或在我收到此错误之前:

密钥无法解析为某种类型

使这项工作的最佳解决方案是什么?

Sriram Narayan说要对Key进行字符串编码,以使其通过GWT的RPC机制:

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class SomeDomainClass implements Serializable {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
@Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
String id;

您引用的第二个教程有一个关于遮蔽com.google.appengine.api.datastore.Key类的部分,因为它不适用于GWT:

因为我没有在客户端上使用Key类做任何事情,所以我要将其删除。 这实际上需要几个步骤,并涉及GWT XML模块文件的超级srcfunction。

您可能需要查看GWT文档 ,其中说明了这一点

GWT的核心是将Java源代码转换为JavaScript的编译器

因此,您需要使用源代码才能在客户端代码中使用给定的类。

一旦你厌倦了JDO,看看客观化 。 我发现它可以更好地使用它,并且它具有完整的GWT互操作而无需DTO。

您可以通过添加这些额外的jar文件来使用GWT代码中的Key类:

http://www.resmarksystems.com/code/

  • AppEngine上-utils的客户端 – 1.0.jar
  • AppEngine上-utils的服务器-1.0.jar

这基本上为GWT编译器提供了一个GWT友好版本的Key和其他AppEngine类。 (如Text,Blob和User ..)

使用:

  • 在构建路径中的任何位置添加appengine-utils-client-1.0.jar。
  • 将appengine-utils-server-1.0.jar放在WEB-INF / lib文件夹中。
  • 将以下内容添加到GWT模块:

另一种选择是实现您在客户端中使用的DTO(数据传输对象),而不是直接使用持久对象。 或者,您可以转到JPA而不是JDO。 在appengine JPA文档中的示例数据类中,Id是Long而不是Key实现http://code.google.com/appengine/docs/java/datastore/usingjpa.html

难道你忘了为RPCCallsService创建实现吗? 我无法从您拥有的文件列表中看到它。

您应该在RPCCalls / src / com / example / rpccalls / server /中有一个名为RPCCallsServiceImpl.java的文件,它是接口RPCCallsService.java的实现文件。

它看起来像这样:

 import javax.jdo.JDOHelper; import javax.jdo.PersistenceManager; import javax.jdo.PersistenceManagerFactory; import com.google.gwt.user.server.rpc.RemoteServiceServlet; import com.example.rpccalls.client.RPCCallsService; public class RPCCallsServiceImpl extends RemoteServiceServlet implements RPCCallsService { // Factory to get persistence manager object later private static final PersistenceManagerFactory PMF = JDOHelper.getPersistenceManagerFactory("transactional-optional"); public String saveName(Person p) { // Data Store need persistence manager object for writing to it PersistenceManager pm = PMF.getPersistenceManager(); // Recommended way to save an object to the data store try { pm.makePersistent(p); } finally { pm.close(); } // You want it to return string return p.getName(); } } 

希望这有助于您解决问题。 干杯:)