5

我正在尝试在我的应用程序中实现 RequestFactory 和 Editor 框架。即使在研究了论坛、谷歌开发者论坛和其他论坛之后,我也发现对于将 RequestContext 与 RequestFactory 一起使用,我不了解一些基本的东西。这是我的场景:
我有一个简单的实体,它具有三个字段,id、版本、描述,称为 CmsObjectType。我的 CRUD 操作有一个相应的 EntityProxy 和一个 CmsObjectTypeServiceDAO。我还实现了 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();
}
}

当我创建一个新的请求上下文并链接我的方法调用以创建、更新和删除然后调用 fire() 时,它在上面的测试中没有问题。但是,如果我尝试通过调用该方法然后 fire() 单独执行这些调用,我会遇到问题。我可以调用 create() ,接收器返回新创建的实体的 id,然后我使用该 id 调用 find(id) 并取回新创建的实体。到目前为止,一切正常。但是,这是我感到困惑的地方。如果我尝试从 find(id) 接收器的 onSuccess() 方法中使用当前 RequestContext 调用编辑,我会收到一条错误消息,指出上下文已经在进行中。如果我为 foundProxy 创建一个局部变量,然后尝试使用 RequestContext 的新实例来调用 requestContext。在新找到的实体上编辑(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 为空并且事情不会更新。代理是否必须与创建它们的上下文保持绑定才能对其执行更新?如果有人可以解释这是如何工作的,或者向我指出一些指出我所缺少的文档,我将不胜感激。这可能与测试框架处理请求的方式有关吗?我已阅读以下内容,如果我遗漏了其中的内容,请告诉我: tbroyer 的精彩描述

谷歌文档 任何帮助将不胜感激。谢谢!

4

1 回答 1

18

查看RequestFactoryTestGWT 源代码中的示例。该 testChangedEdit()方法类似于您要编写的方法。它调用一个find()方法,然后对onSuccess()方法中返回的代理进行操作。

ARequestContext不是长期存在的对象。它仅在您调用fire()它时有效。只有在你onFailure()的.onViolation()Receiver

一个EntityProxyValueProxy返回的 viaReceiver.onSuccess()表示服务器数据的快照。RequestContext因此,代理是不可变的,除非它通过调用与 a 相关联edit()。返回的代理RequestContext.create()是可变的。可变代理总是与一个代理相关联,并且“跨流RequestContext”是错误的。这不是可变代理的错误。re-edit()

它以这种方式工作的原因是允许 RequestFactory 客户端仅将增量发送到服务器。find()通过调用域对象的方法(或使用)将增量应用于服务器上的长期实体Locator。RequestContext 本质上是proxy.setFoo()调用和一个或多个Request/InstanceRequest调用的累加器。

一般准则:

  • 不要将 RequestContext 实例存储在生命周期超过fire()方法调用的对象的字段中。
  • 同样,可编辑的EntityProxyValueProxy实例不应该在调用之外保留fire()
  • EntityProxyId返回的 from可以EntityProxy.stableId() 无限期地保留,即使是来自新创建的代理。该stableId对象适合用作对象中的键Map并且具有稳定的对象身份语义(即同一服务器域对象的不同版本的两个快照将返回相同的'EntityProxyId')。
  • 的实例RequestFactory应该构建一次并在模块的生命周期内保留,因为它们具有不小的构建成本。
于 2011-04-12T22:31:30.350 回答