我正在尝试将RequestFactory和Editor框架实现到我的应用程序中。我甚至在研究了论坛,谷歌开发者论坛以及其他人之后发现,有些基本的东西我不理解将RequestContext与RequestFactory一起使用。这是我的情景:
我有一个简单的实体,它有三个字段,id,version,描述名为CmsObjectType。我有一个对应的EntityProxy和一个CmsObjectTypeServiceDAO与我的CRUD操作。我还实现了ServiceLocator和ObjectLocator类。这段代码全部编译并运行。
我还创建了一个简单的测试用例来测试CRUD操作,使用以下命令:
public class RequestFactoryProvider {
public static CmsRequestFactory get() {
SimpleEventBus eventBus = new SimpleEventBus();
CmsRequestFactory requestFactory = RequestFactoryMagic.create(CmsRequestFactory.class);
ServiceLayer serviceLayer = ServiceLayer.create();
SimpleRequestProcessor processor = new SimpleRequestProcessor(
serviceLayer);
requestFactory.initialize(eventBus, new InProcessRequestTransport(
processor));
return requestFactory;
}
}
测试:
public class TestCmsObjectTypeRequest extends Assert {
private static CmsRequestFactory requestFactory;
private static CmsObjectTypeRequestContext objectTypeRequest;
private Long newId;
@Before
public void setUp() {
requestFactory = RequestFactoryProvider.get();
objectTypeRequest = requestFactory.objectTypeRequest();
}
@Test
public void testEdit() {
final CmsObjectTypeProxy newType = objectTypeRequest
.create(CmsObjectTypeProxy.class);
newType.setDescription("NEW TYPE");
objectTypeRequest.persist(newType).to(new Receiver<Long>() {
@Override
public void onSuccess(Long response) {
if (response != null) {
newId = response;
assertTrue(true);
} else {
fail();
}
}
@Override
public void onFailure(ServerFailure error) {
fail();
}
});
// Edit the newly created object
newType.setDescription("EDITED NEW TYPE");
objectTypeRequest.update(newType).to(new Receiver<Boolean>() {
@Override
public void onSuccess(Boolean response) {
assertTrue(response);
}
@Override
public void onFailure(ServerFailure error) {
fail();
}
});
//Remove it when we're done..
objectTypeRequest.delete(newType).to(new Receiver<Boolean>() {
@Override
public void onSuccess(Boolean response) {
System.out.println("onSuccess from delete.");
assertTrue(response);
}
@Override
public void onFailure(ServerFailure error) {
fail();
}
});
objectTypeRequest.fire();
}
}
当我创建一个新的请求上下文并链接我的方法调用create,update和delete然后调用fire()时,它在上面的测试中没有问题。但是,如果我尝试通过调用方法单独执行这些调用然后fire()我会遇到问题。我可以调用create(),Receiver返回新创建的实体的id,然后我使用该id调用find(id),然后我返回新创建的实体。到目前为止一切正常。但是,这是我感到困惑的地方..如果我尝试使用查找(id)中Receiver的onSuccess()方法中的当前RequestContext调用edit,我会收到一条错误消息,说明上下文已在进行中。如果我为foundProxy创建一个局部变量,然后尝试使用RequestContext的新实例在新发现的实体上调用requestContext.edit(foundProxy),然后调用update()我得到一个服务器错误,最常见的是:服务器错误:请求的实体在服务器上不可用。如果我不创建请求上下文的新实例,我会收到IllegalStateException,表示请求已在进行中。 以下是样本测试,希望能让这个更清晰:
@Test
public void testEditWOChaining() {
final CmsObjectTypeProxy newType = objectTypeRequest
.create(CmsObjectTypeProxy.class);
newType.setDescription("NEW TYPE");
objectTypeRequest.persist(newType).to(new Receiver<Long>() {
@Override
public void onSuccess(Long response) {
if (response != null) {
setNewId(response);
assertTrue(true);
} else {
fail();
}
}
@Override
public void onFailure(ServerFailure error) {
fail();
}
}).fire();
if (newId != null) {
objectTypeRequest = requestFactory.objectTypeRequest();
objectTypeRequest.find(newId)
.to(new Receiver<CmsObjectTypeProxy>() {
@Override
public void onSuccess(CmsObjectTypeProxy response) {
if (response != null) {
foundProxy = response;
}
}
@Override
public void onFailure(ServerFailure error) {
fail();
}
}).fire();
}
if (foundProxy != null) {
// Edit the newly created object
objectTypeRequest = requestFactory.objectTypeRequest();
CmsObjectTypeProxy editableProxy = objectTypeRequest
.edit(foundProxy);
editableProxy.setDescription("EDITED NEW TYPE");
objectTypeRequest.update(editableProxy).to(new Receiver<Boolean>() {
@Override
public void onSuccess(Boolean response) {
assertTrue(response);
}
@Override
public void onFailure(ServerFailure error) {
fail();
}
}).fire();
}
// Remove it when we're done..
objectTypeRequest.delete(foundProxy).to(new Receiver<Boolean>() {
@Override
public void onSuccess(Boolean response) {
System.out.println("onSuccess from delete.");
assertTrue(response);
}
@Override
public void onFailure(ServerFailure error) {
fail();
}
});
objectTypeRequest.fire();
}
以下是我的问题..如果编辑没有与create()相关但是使用find(),那么处理编辑的最佳方法是什么?如果我尝试使用更新链接查找,我的foundProxy为null,并且事情不会更新。代理必须保持绑定到创建它们的上下文,以便能够对它们执行更新吗?如果有人可以解释这是如何工作的,或者指出一些文件,指出我错过了什么,我将不胜感激。这是否可能与测试框架处理请求的方式有关? 我已阅读以下内容,如果我遗漏了其中的内容,请告诉我: Great description by tbroyer
Google docs 任何帮助将不胜感激。谢谢!
答案 0 :(得分:18)
请查看GWT源代码中的RequestFactoryTest
以获取示例。 testChangedEdit()
方法类似于您尝试编写的方法。它调用find()
方法,然后在onSuccess()
方法中对返回的代理进行操作。
RequestContext
不是长期存在的对象。只有当您在其上调用fire()
时,它才会被调用。只有在onFailure()
中调用onViolation()
或Receiver
方法时,才能重复使用它。
通过EntityProxy
返回的ValueProxy
或Receiver.onSuccess()
表示服务器数据的快照。因此,代理是不可变的,除非它通过调用RequestContext
与edit()
相关联。 RequestContext.create()
返回的代理是可变的。可变代理始终只与一个RequestContext
相关联,而“cross the streams”则出错。 re-edit()
可变代理不是错误。
它以这种方式工作的原因是允许RequestFactory客户端仅向服务器发送增量。通过调用域对象的find()
方法(或使用Locator
),将增量应用于服务器上的长期实体。 RequestContext本质上是proxy.setFoo()
个调用和一个或多个Request
/ InstanceRequest
个调用的累加器。
一般准则:
fire()
方法调用的对象的字段中。EntityProxy
的调用之外,不应保留可编辑的ValueProxy
或fire()
个实例。EntityProxyId
返回的EntityProxy.stableId()
可以无限期保留,即使是来自新创建的代理也是如此。 stableId
对象适合用作Map
对象中的键,并具有稳定的对象标识语义(即具有不同版本的同一服务器域对象的两个快照将返回相同的`EntityProxyId')。 RequestFactory
的实例应该构建一次,并在模块的生命周期内保留,因为它们具有非常重要的构建成本。