阐明GWT RequestFactory和RequestContext的工作方式

| 我正在尝试在我的应用程序中实现RequestFactory和Editor框架。在研究了该论坛,Google Developer论坛以及其他论坛之后,我仍然发现,将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();
}
}
当我创建一个新的请求上下文并链接我的方法时,它会调用create,update和delete,然后调用fire(),在上面的测试中它没有问题。但是,如果我尝试通过调用方法分别执行这些调用,然后执行fire(),则会遇到问题。我可以使用Receiver调用create()来返回新创建的实体的ID,然后使用该ID来调用find(id),然后取回新创建的实体。至此,一切正常。但是,这是我感到困惑的地方。.如果我尝试从find(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,并且不会更新。为了能够对其进行更新,代理是否必须与创建它们的上下文保持联系?如果有人可以解释这是如何工作的,或者将我指向一些指出我所缺少的文档,我将不胜感激。这可能与测试框架处理请求的方式有关吗? 我已阅读以下内容,因此,如果我错过了其中的内容,请告诉我: tbroyer的精彩描述 谷歌文档 任何帮助将不胜感激。谢谢!     
已邀请:
请看一下GWT源代码中的ѭ3。
testChangedEdit()
方法类似于您尝试编写的方法。它调用
find()
方法,然后以
onSuccess()
方法对返回的代理进行操作。
RequestContext
不是长寿的物体。它仅在被调用之时至调用ѭ8call时才有效。仅当在您的
Receiver
中调用
onFailure()
onViolation()
方法时,才能重新使用它。 通过
Receiver.onSuccess()
返回的
EntityProxy
ValueProxy
代表服务器数据的快照。因此,除非代理通过调用
edit()
RequestContext
关联,否则它是不可变的。
RequestContext.create()
返回的代理是可变的。可变代理始终始终与一个7关联,并且“跨流”是错误的。对可变代理进行19也不是错误。 它以这种方式工作的原因是允许RequestFactory客户端仅将增量发送到服务器。通过调用域对象的
find()
方法(或使用
Locator
),将增量应用于服务器上的长期实体。 RequestContext本质上是用于“ 22”个调用和一个或多个“ 23” /“ 24”调用的累加器。 一般准则: 不要将RequestContext实例存储在生存期超过“ 8”方法调用的生存期的对象的字段中。 同样,在调用
fire()
之前,不应保留可编辑的beyond12ѭ或
ValueProxy
实例。 从
EntityProxy.stableId()
返回的
EntityProxyId
可以无限期保留,即使是从新创建的代理中也是如此。
stableId
对象适合用作
Map
对象中的键,并具有稳定的对象身份语义(即,同一服务器域对象的两个版本不同的快照将返回相同的“ EntityProxyId \”)。 ѭ33的实例应构造一次,并在模块的生命周期内保留,因为它们的造价不菲。     

要回复问题请先登录注册