将Generics与GWT-RPC一起使用并不像预期的那样工作

时间:2014-02-10 20:13:03

标签: java generics gwt gwt-rpc

我尝试使用泛型创建单个服务,而不是创建一百个不同的GWT-RPC服务和serviceAsync类。这是界面:

@RemoteServiceRelativePath("dispatch")
public interface CommandService extends RemoteService
{
    public <T> Result<T> execute(Command command, T target);
}

此处Command是我可以发出的所有不同命令的枚举,例如Login, Register, ChangePassword'等。在服务器端,我有HashMap {{} 1}}作为键,Command类作为值。对于每个Executor,我都有相应的Command。执行Executor,并在服务器端返回其返回值。

当我尝试在客户端上创建Executor并尝试执行它时,会出现问题。这是我的代码:

CommandServiceAsync

这里,public enum Command { LOGIN, REGISTER, CHANGE_PW; public <T> void execute(T target, final ResultReceiver<T> receiver) { CommandServiceAsync command = GWT.create(CommandService.class ); command.execute(this, target, new AsyncCallback<Result<T> >() { @Override public void onFailure(Throwable caught) { MyProgram.handleFailure(caught); } @Override public void onSuccess(Result<T> result) { receiver.receive( result );; } }); } } 是实际调用服务的方法。这是我如何调用它来执行Command.execute命令:

LOGIN

问题发生在LoginForm form = new LoginForm(); Command.LOGIN.execute(form, new ResultReceiver<LoginForm>() { @Override public void receive(Result<LoginForm> result) { Console.debug("Received result"); //result.getTarget() will return an instance of LoginForm Console.debug("user: " + result.getTarget().getUser() ); Console.debug("pw: " + result.getTarget().getUser() ); } }); 中的以下一行:

Command.execute

在这里,我收到以下错误:

  

错误:'com.xxx.CommandService'的延迟绑定失败;期望   后续失败

     

错误:未捕获的异常已转义   com.google.gwt.event.shared.UmbrellaException:捕获异常:   'com.xxx.CommandService'的延迟绑定失败(你忘记了吗?   继承一个必需的模块?)

     

引起:   com.google.gwt.core.ext.UnableToCompleteException :(参见上一个日志   条目)

我怎样才能完成我想要做的事情?

2 个答案:

答案 0 :(得分:5)

在客户端GWT应用程序中,必须在编译时知道所有类型。拥有像你所描述的那样的通用方法是行不通的。

你可以尝试类似下面的内容

public interface CommandService extends RemoteService {
    public Result<Serializable> execute(Command command, Serializable target);
}

你会失去一些类型安全并限制你一点,但这应该有用。

Request Factory可能更适合这种情况。它提供了很多关于服务器端代码执行实际工作的方面的宽容。

GWT源中有一个Request Factory示例项目。 gwtproject.org网站上有关于获取源代码here的非常明确的说明。查看eclipse目录中的README文件。这将有助于您入门。

修改

正如@ColinAlworth指出的那样,在RPC方法中使用简单接口时,你应该非常小心。上面的方法告诉编译器它应该能够通过它有权访问的线路发送每个Serializable对象,并为每一个创建序列化器和反序列化器!

答案 1 :(得分:1)

使用GWT-RPC的genrics和Object类是一种糟糕的方法。有时候它会抛出一个序列化异常,有时它不会,但它不起作用。原因是,GWT在编译时创建白名单或序列化策略。为此,您需要知道您正在使用的确切类。 有关详细信息,请查看以下链接

Serialization Exception while making an RPC call