Java GWT请求工厂+;ServiceLocator错误

Java GWT请求工厂+;ServiceLocator错误,java,gwt,requestfactory,Java,Gwt,Requestfactory,我在RequestFactory中使用GWT2.2。该应用程序有一个现有的服务层(服务器端),所以我使用ServiceLocator来提供这些实现。My Proxy和RequestContext指定要使用的正确服务和定位器(如图所示)。我可以对数据进行基本请求,但当我尝试保存时,会出现以下异常: com.google.gwt.requestfactory.server.UnexpectedException: Could not instantiate Locator com.schedgy.c

我在RequestFactory中使用GWT2.2。该应用程序有一个现有的服务层(服务器端),所以我使用ServiceLocator来提供这些实现。My Proxy和RequestContext指定要使用的正确服务和定位器(如图所示)。我可以对数据进行基本请求,但当我尝试保存时,会出现以下异常:

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
}
OrganizationRequest看起来像:

public class CompanyServiceLocator implements ServiceLocator {

    protected Injector injector;

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

    @Override
    public Object getInstance(Class<?> clazz) {
        return injector.getInstance(clazz);
    }
}
@ProxyFor(value=Organization.class, locator=OrganizationService.class)
public interface OrganizationProxy extends CompanyEntityProxy {
... setters/getters defined here
}
@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并重写ServiceLocator以使用Guice创建服务实例的原因。但是为什么第一个调用正确使用my ServiceLocator,而第二个调用没有正确使用?

定位器必须是默认的可实例化的

@ProxyFor(value=Organization.class, locator=OrganizationService.class)
这就是事情偏离轨道的地方。如果
OrganizationService
正在出售
Organization
的实例以实现
Locator
接口,则需要将其设置为默认实例,或插入实现
createLocator()
ServiceLayerDecorator


第一个代码示例有效而不是第二个代码示例有效的原因是,第二个代码示例正在基于来自客户端的命令创建和修改组织。在这种情况下,RequestFactory服务器代码必须调用Locator.create()。在不知道
paginate()
返回给客户端的内容的情况下,我怀疑没有返回
组织的实例,因为有必要调用
定位器.getId()
定位器.getVersion()
方法。

定位器必须是默认实例

@ProxyFor(value=Organization.class, locator=OrganizationService.class)
这就是事情偏离轨道的地方。如果
OrganizationService
正在出售
Organization
的实例以实现
Locator
接口,则需要将其设置为默认实例,或插入实现
createLocator()
ServiceLayerDecorator


第一个代码示例有效而不是第二个代码示例有效的原因是,第二个代码示例正在基于来自客户端的命令创建和修改组织。在这种情况下,RequestFactory服务器代码必须调用Locator.create()
。在不知道
paginate()
返回给客户端的内容的情况下,我怀疑没有返回
组织的实例,因为有必要调用
Locator.getId()
Locator.getVersion()
方法。

我仍然不明白为什么两个类需要为定位器提供实现,但我是如何解决这个问题的

扩展默认的RequestFactoryServlet,以便可以在默认情况下插入自定义ServiceLayerCorator

public class CompanyRequestFactoryServlet extends RequestFactoryServlet {

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

    public SchedgyRequestFactoryServlet(ExceptionHandler exceptionHandler,
            ServiceLayerDecorator... serviceDecorators) {
        super(exceptionHandler, serviceDecorators);
    }
}
创建ServiceLayerDecorator以提供定位器的实例。我使用Guice,所以这很简单。下面代码中的GuiceFactory只是一个提供Guice注入器实例的单例

public class CompanyServiceLayerDecorator extends ServiceLayerDecorator {

    @Override
    public <T extends Locator<?, ?>> T createLocator(Class<T> clazz) {
        return GuiceFactory.getInjector().getInstance(clazz);
    }
}
公共类公司ServiceLayerCorator扩展ServiceLayerCorator{
@凌驾

public我仍然不明白为什么两个类需要为定位器提供实现,但下面是我如何解决这个问题的

扩展默认的RequestFactoryServlet,以便可以在默认情况下插入自定义ServiceLayerCorator

public class CompanyRequestFactoryServlet extends RequestFactoryServlet {

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

    public SchedgyRequestFactoryServlet(ExceptionHandler exceptionHandler,
            ServiceLayerDecorator... serviceDecorators) {
        super(exceptionHandler, serviceDecorators);
    }
}
创建ServiceLayerDecorator以提供定位器的实例。我使用Guice,因此这非常简单。下面代码中的GuiceFactory只是一个提供Guice注入器实例的单例

public class CompanyServiceLayerDecorator extends ServiceLayerDecorator {

    @Override
    public <T extends Locator<?, ?>> T createLocator(Class<T> clazz) {
        return GuiceFactory.getInjector().getInstance(clazz);
    }
}
公共类公司ServiceLayerCorator扩展ServiceLayerCorator{
@凌驾

public您正在使用的@Proxy和@Service批注是什么?错误消息看起来您在其中一个批注中将非默认的instantiable OrganizationService用作定位器值的目标。不,我非常确定它们是正确的。同样,在获取数据时它工作正常。我只在保存时遇到问题一个实体。我更新了问题以包括代理接口和请求上下文,以便您可以看到。您正在使用的@Proxy和@Service批注是什么?错误消息看起来您在其中一个批注中将非默认的Instanceable OrganizationService用作定位器值的目标。不,我非常确定它们是正确的。同样,当我获取数据时,它工作正常。我只在保存实体时出现问题。我更新了问题以包括代理接口和请求上下文,以便您可以看到。让CompanyServiceLocator提供OrganizationService实例的目的是什么?是服务吗(定位器的实现)现在由两个不同的类(ServiceLayerDecorator和ServiceLocator的实现)提供/实例化?服务由ServiceLocator提供;实体由Locator提供。RequestFactory创建一个(ServiceLocator或Locator)使用他们的无参数构造函数,除非您提供ServiceLayerDecorator来更改该行为。您可能很难理解谁在做什么,因为您的服务和您的“操作实体定位器”在您的案例中是同一个类(老实说,我不太明白为什么)@Thomas,我有两个不同的类:CompanyServiceLocator提供服务,OrganizationService提供“运营实体定位器”.我不明白它们是怎么一回事?也许我在提出这个问题方面做得不够好,但我相信责任是正确划分的。如果不是,我想听听为什么,以便我可以纠正它们。我的意思是,组织服务既是你的服务,也是定位程序。事实上,你的公司服务定位于或者将提供“作为服务”的实例(