1

RequestFactory で GWT 2.2 を使用しています。アプリには既存のサービス レイヤー (サーバー側) があるため、これらの実装を提供するために ServiceLocator を使用しています。My Proxy と RequestContexts は、使用する正しいサービスとロケーターを指定します (ここに示すように)。データの基本的なリクエストを行うことはできますが、保存しようとすると、次の例外が発生します。

com.google.gwt.requestfactory.server.UnexpectedException: Could not instantiate Locator com.schedgy.core.service.OrganizationService. Is it default-instantiable?
at com.google.gwt.requestfactory.server.ServiceLayerDecorator.die(ServiceLayerDecorator.java:185)
at com.google.gwt.requestfactory.server.LocatorServiceLayer.newInstance(LocatorServiceLayer.java:222)
at com.google.gwt.requestfactory.server.LocatorServiceLayer.createLocator(LocatorServiceLayer.java:47)
at com.google.gwt.requestfactory.server.ServiceLayerDecorator.createLocator(ServiceLayerDecorator.java:54)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

OrganizationService は次のように定義されます。

// Parent class provides the generic Locator<Organization, String> methods
public class OrganizationService extends CompanyEntityService<Organization> {

        protected OrganizationDao organizationDao;

        protected UserDao userDao;

        protected RoleDao roleDao;

        @Inject
        public OrganizationService(
                OrganizationDao organizationDao,
                UserDao userDao,
                RoleDao roleDao) {

            super(organizationDao, Organization.class);

            this.organizationDao = organizationDao;
            this.userDao = userDao;
            this.roleDao = roleDao;
        }

... additional methods
}

私のロケータークラスは次のようになります:

public class CompanyServiceLocator implements ServiceLocator {

    protected Injector injector;

    public CompanyServiceLocator() {        
        injector = GuiceFactory.getInjector();
    }

    @Override
    public Object getInstance(Class<?> clazz) {
        return injector.getInstance(clazz);
    }
}

OrganizationProxy は次のようになります。

@ProxyFor(value=Organization.class, locator=OrganizationService.class)
public interface OrganizationProxy extends CompanyEntityProxy {
... setters/getters defined here
}

OrganizationRequest は次のようになります。

@Service(value=OrganizationService.class, locator=CompanyServiceLocator.class)
public interface OrganizationRequest extends RequestContext {
...
}

クライアント側のコードは次のようになります。

OrganizationRequest req = organizationRequestFactory.request();
req.paginate(0, 10).fire(paginationReceiver); // Works!

req = organizationRequestFactory.request();
OrganizationProxy org = req.create(OrganizationProxy.class);
org.setName("test");
req.save(org).fire(receiver); // This causes the server side exception

デフォルトのコンストラクターがないため、ServiceLayerDecorator が OrganizationService をインスタンス化できないことは明らかですが、これが、私が Guice を使用していて、サービスのインスタンスを作成するために Guice を使用するように ServiceLocator を上書きした理由です。しかし、最初の呼び出しでは ServiceLocator が正しく使用されるのに、2 番目の呼び出しでは正しく使用されないのはなぜですか?

4

2 に答える 2

4

ロケーターはデフォルトでインスタンス化可能である必要があります。

@ProxyFor(value=Organization.class, locator=OrganizationService.class)

物事が軌道から外れているところです。がインターフェースを満たすためにOrganizationServiceインスタンスを販売している場合は、それをデフォルトインスタンス化可能にするか、を実装するを注入する必要があります。OrganizationLocatorServiceLayerDecoratorcreateLocator()

Organization最初のコードサンプルが機能し、2番目のコードサンプルが機能しない理由は、2番目のコードサンプルがクライアントからのコマンドに基づいて作成および変更しているためです。この場合Locator.create()、RequestFactoryサーバーコードによって呼び出される必要があります。paginate()何がクライアントに返されるかわからないので、メソッドとメソッドOrganizationを呼び出す必要があるため、のインスタンスは返されていないと思います。Locator.getId()Locator.getVersion()

于 2011-04-05T14:17:34.607 に答える
1

2つのクラスがロケーターの実装を提供する必要がある理由についてはまだ混乱していますが、この問題を修正する方法は次のとおりです。

デフォルトのRequestFactoryServletを拡張して、カスタムのServiceLayerDecoratorをデフォルトで挿入できるようにします。

public class CompanyRequestFactoryServlet extends RequestFactoryServlet {

    public CompanyRequestFactoryServlet() {
        this(new DefaultExceptionHandler(), new CompanyServiceLayerDecorator());
    }

    public SchedgyRequestFactoryServlet(ExceptionHandler exceptionHandler,
            ServiceLayerDecorator... serviceDecorators) {
        super(exceptionHandler, serviceDecorators);
    }
}

ServiceLayerDecoratorを作成して、ロケーターのインスタンスを提供します。Guiceを使っているので、とても簡単でした。以下のコードのGuiceFactoryは、GuiceInjectorのインスタンスを提供する単なるシングルトンです。

public class CompanyServiceLayerDecorator extends ServiceLayerDecorator {

    @Override
    public <T extends Locator<?, ?>> T createLocator(Class<T> clazz) {
        return GuiceFactory.getInjector().getInstance(clazz);
    }
}

最後に、カスタムサーブレットを使用するようにweb.xmlを更新します。

<servlet>
    <servlet-name>requestFactoryServlet</servlet-name>
    <servlet-class>com.company.core.requestfactory.CompanyRequestFactoryServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>requestFactoryServlet</servlet-name>
    <url-pattern>/gwtRequest</url-pattern>
</servlet-mapping>
于 2011-04-06T15:15:19.340 に答える