将不可变类的 ValueProxy 发送到上游服务器
假设我尝试使用 GWT 的 RequestFactory 在客户端和服务器之间双向传递不可变类型。假设底层类型是 TimeOfDay,它被设计为不可变的:
public class TimeOfDay {
private final int hours;
private final int minutes;
public TimeOfDay(final int hours, final int minutes) {...}
public int getHours() {...}
public int getMinutes() {...}
}
我可以使用 ValueProxy 代理此类:
@ProxyFor(TimeOfDay.class)
public interface TimeOfDayProxy extends ValueProxy {
public int getHours();
public int getMinutes();
}
现在,我可以非常轻松地在服务器端创建 TimeOfDay 实例,并通过服务器端的以下方法将它们返回给客户端:
public class TimeOfDayService {
public static TimeOfDay fetchCurrentTofD() {
return new TimeOfDay(16, 20);
}
}
...这在客户端:
@Service(TimeOfDayService.class)
public interface TimeOfDayRequestContext extends RequestContext {
Request<TimeOfDayProxy> fetchCurrentTofD();
}
...
final Receiver<TimeOfDayProxy> receiver = new Receiver<TimeOfDayProxy>() {...};
final TimeOfDayRequestContext context = myFactory.timeOfDayRequestContext();
final Request<TimeOfDayProxy> fetcher = context.fetchCurrentTofD();
fetcher.fire(receiver);
...
这非常有效。但是,如果我朝相反的方向尝试,就会遇到障碍。即,在服务器端:
public class TimeOfDayService {
public static void setCurrentTofD(final TimeOfDay tofd) {...}
}
...在客户端:
@Service(TimeOfDayService.class)
public interface TimeOfDayRequestContext extends RequestContext {
Request<Void> setCurrentTofD(TimeOfDayProxy tofd);
}
...
final Receiver<Void> receiver = new Receiver<Void>() {...};
final TimeOfDayRequestContext context = myFactory.timeOfDayRequestContext();
final TimeOfDayProxy tofdProxy = GWT.create(TimeOfDayProxy.class);
<???>
final Request<Void> setter = context.setCurrentTofD(tofdProxy);
setter.fire(receiver);
...
问题#1 是我无法设置 tofdProxy 的(不可变)内容,因为 GWT.create() 只是创建一个默认构造的代理(即“???”的地方?)。问题 #2 是服务器端的“No setter”错误。
有什么魔法可以绕过这些障碍吗? AutoBeanFactory.create() 有一个双参数变体,它接受一个由 autobean 包装的对象 --- 类似的东西会处理 Snag #1 (如果 ValueProxys 的 create() 存在这样的东西)。至于第二个问题,我相信有很多聪明的方法可以解决这个问题;问题是,GWT 中已经实现了吗?
Suppose I am trying to use GWT's RequestFactory to pass an immutable type between client and server, bidirectionally. Let's say the underlying type is TimeOfDay, which is designed to be immutable:
public class TimeOfDay {
private final int hours;
private final int minutes;
public TimeOfDay(final int hours, final int minutes) {...}
public int getHours() {...}
public int getMinutes() {...}
}
I can proxy this class with a ValueProxy:
@ProxyFor(TimeOfDay.class)
public interface TimeOfDayProxy extends ValueProxy {
public int getHours();
public int getMinutes();
}
Now, I can quite easily create TimeOfDay instances on the server side and return them to the client, via this on server side:
public class TimeOfDayService {
public static TimeOfDay fetchCurrentTofD() {
return new TimeOfDay(16, 20);
}
}
...and this on the client side:
@Service(TimeOfDayService.class)
public interface TimeOfDayRequestContext extends RequestContext {
Request<TimeOfDayProxy> fetchCurrentTofD();
}
...
final Receiver<TimeOfDayProxy> receiver = new Receiver<TimeOfDayProxy>() {...};
final TimeOfDayRequestContext context = myFactory.timeOfDayRequestContext();
final Request<TimeOfDayProxy> fetcher = context.fetchCurrentTofD();
fetcher.fire(receiver);
...
This works great. But, if I try this in the reverse direction I hit snags. I.e., on server side:
public class TimeOfDayService {
public static void setCurrentTofD(final TimeOfDay tofd) {...}
}
...and on client side:
@Service(TimeOfDayService.class)
public interface TimeOfDayRequestContext extends RequestContext {
Request<Void> setCurrentTofD(TimeOfDayProxy tofd);
}
...
final Receiver<Void> receiver = new Receiver<Void>() {...};
final TimeOfDayRequestContext context = myFactory.timeOfDayRequestContext();
final TimeOfDayProxy tofdProxy = GWT.create(TimeOfDayProxy.class);
<???>
final Request<Void> setter = context.setCurrentTofD(tofdProxy);
setter.fire(receiver);
...
Snag #1 is that I have no way to set the (immutable) contents of tofdProxy, since GWT.create() just makes a default constructed proxy (i.e. what goes in place of "???"?). Snag #2 is the "No setter" error on the server side.
Is there some magic to circumvent these snags? AutoBeanFactory.create() has a two-argument variant which takes an object to be wrapped by an autobean --- something like that would take care of Snag #1 (if such a thing existed for create() of ValueProxys). As for Snag #2, well, I'm sure there are many clever approaches to deal with the issue; the question is, have any been implemented yet in GWT?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
RequestFactory 需要带有设置器的默认可实例化类,用于客户端到服务器的通信。
有一个待处理的增强请求,要求使用构建器模式添加对不可变类的支持:http://code.google.com/p/google-web-toolkit/issues/detail?id=5604
RequestFactory requires default-instantiable classes with setters for client-to-server communications.
There's a pending request for enhancement to add support for immutable classes, using a builder pattern: http://code.google.com/p/google-web-toolkit/issues/detail?id=5604