java - 将泛型与 GWT-RPC 一起使用未按预期工作

标签 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 等。在服务器端,我以 CommandHashMap 作为键,以 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 中的以下行:

CommandServiceAsync command = GWT.create(CommandService.class );

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

ERROR: Deferred binding failed for 'com.xxx.CommandService'; expect subsequent failures

ERROR: Uncaught exception escaped com.google.gwt.event.shared.UmbrellaException: Exception caught: Deferred binding failed for 'com.xxx.CommandService' (did you forget to inherit a required module?)

Caused by: com.google.gwt.core.ext.UnableToCompleteException: (see previous log entries)

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

最佳答案

在客户端 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 方法中使用简单接口(interface)时,您应该非常小心。上面的方法告诉编译器它应该能够通过它有权访问的线路发送每个可序列化对象,并且将为每个对象创建序列化器和反序列化器!

关于java - 将泛型与 GWT-RPC 一起使用未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21686978/

相关文章:

java - 嵌套循环中没有中断?

c# - C# 中空泛型参数 <,> 的术语是什么?

gwt - 带换行符的GWT标签

java - 使用 Spring Mvc 测试测试 Spring Security Controller

java - 添加 String Literals 和 String 对象之间的区别

java - 对孤立的 arraylist 元素执行乘法

java - 具有多种泛型类型的 ArrayList?

java - 如何以通用方式使用算术运算来减少原始数组?

java - 使用 GWT 检查图像的大小

javascript - GWT IFrame Javascript 错误