IAm*_*aja 1 java gwt server-communication requestfactory
我有以下Java servlet执行我称之为" 添加服务 ":
public class AdditionService extends HttpServlet {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) {
// The request will have 2 Integers inside its body that need to be
// added together and returned in the response.
Integer addend = extractAddendFromRequest(request);
Integer augend = extractAugendFromRequest(request);
Integer sum = addend + augend;
PrintWriter writer = response.getWriter();
writer.write(sum);
}
}
Run Code Online (Sandbox Code Playgroud)
我试图让GWT的RequestFactory做同样的事情(在应用服务器上添加两个数字并将总和作为响应返回)使用ValueProxy和AdditionService,并且遇到了一些问题.
这是AdditionRequest(客户端层),它是一个包含两个要添加的整数的值对象:
// Please note the "tier" (client, shared, server) I have placed all of my Java classes in
// as you read through the code.
public class com.myapp.client.AdditionRequest {
private Integer addend;
private Integer augend;
public AdditionRequest() {
super();
this.addend = 0;
this.augend = 0;
}
// Getters & setters for addend/augend.
}
Run Code Online (Sandbox Code Playgroud)
接下来我的代理(客户端层):
@ProxyFor(value=AdditionRequest.class)
public interface com.myapp.client.AdditionRequestProxy extends ValueProxy {
public Integer getAddend();
public Integer getAugend();
public void setAddend(Integer a);
public void setAugend(Integer a);
}
Run Code Online (Sandbox Code Playgroud)
接下来我的服务API(在共享层中):
@Service(value=DefaultAdditionService.class)
public interface com.myapp.shared.AdditionService extends RequestContext {
Request<Integer> sum(AdditionRequest request);
}
Run Code Online (Sandbox Code Playgroud)
接下来我的请求工厂(共享层):
public class com.myapp.shared.ServiceProvider implements RequestFactory {
public AdditionService getAdditionService() {
return new DefaultAdditionService();
}
// ... but since I'm implementing RequestFactory, there's about a dozen
// other methods GWT is forcing me to implement: find, getEventBus, fire, etc.
// Do I really need to implement all these?
}
Run Code Online (Sandbox Code Playgroud)
最后魔术发生的地方(服务器层):
public class com.myapp.server.DefaultAdditionService implements AdditionService {
@Override
public Request<Integer> sum(AdditionRequest request) {
Integer sum = request.getAddend() + request.getAugend();
return sum;
}
// And because AdditionService extends RequestContext there's another bunch of
// methods GWT is forcing me to implement here: append, create, isChanged, etc.
// Do I really need to implement all these?
}
Run Code Online (Sandbox Code Playgroud)
这是我的问题:
AdditionService(在共享的)引用DefaultAdditionService,它在服务器上,它不应该做.共享类型应该能够在客户端和服务器上同时存在,但不能依赖于...ServiceProvider是一个实现的类RequestFactory,还是应该是一个扩展它的接口?如果是后者,我在哪里定义ServiceProviderimpl,以及如何将它链接回所有这些其他类?ServiceProvider和DefaultAdditionService?我是否需要实施所有20多种核心GWT方法?或者我是否正确地使用API或者不像我使用它那样简单?我认为我很接近但需要帮助越过终点线.如果有人可以接受我的代码并调整它以显示使用RF/ValueProxies的正确方法,我认为它会将整个框架与我联系在一起...提前感谢!
如果你想使用RF作为一个简单的RPC机制[*]你可以(而且你是对的:只有ValueProxys),但你需要更多ServiceLocator的东西:s(即GWT 2.1.1).
有了ServiceLocator你可以简单地把你的服务实现(比如你的servlet)成为一个真正的服务实例,而不是变成一个实体对象(如用户仅ValueProxyS,没有静态getXyz()方法)所要求的RF协议.注意Locators 的存在,用于从服务器端实体外部化所有这些方法:如果你ValueProxy在任何地方使用,则不需要.
一个ServiceLocator看起来像(取自官方文档):
public class DefaultAdditionServiceLocator implements ServiceLocator {
@Override
public Object getInstance(Class<?> clazz) {
try {
return clazz.newInstance();
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
您需要DefaultAdditionService使用定位器参数对您的注释进行注释,以便RF知道在将您的请求发送到您的服务时应该依赖什么.就像是:
@Service(value = DefaultAdditionService.class, locator = DefaultAdditionServiceLocator.class)
public interface com.myapp.shared.AdditionService extends RequestContext {
// Note here, you need to use the proxy type of your AdditionRequest.
Request<Integer> sum(AdditionRequestProxy request);
}
Run Code Online (Sandbox Code Playgroud)
您的服务将是地球上最简单的事情(无需扩展/实施与RF相关的任何事情):
public class com.myapp.server.DefaultAdditionService {
// The server-side AdditionRequest type.
public Integer sum(AdditionRequest request) {
Integer sum = request.getAddend() + request.getAugend();
return sum;
}
}
Run Code Online (Sandbox Code Playgroud)
如果你拼写错误sum()或者你没有实现在你声明的方法,RequestContext你将收到一个错误.
为了实例RequestContext你需要进行扩展的RequestFactory接口,与公共工厂方法com.myapp.shared.AdditionService.就像是:
public interface AdditionServiceRequestFactory extends RequestFactory {
public com.myapp.shared.AdditionService createAdditionServiceRequestContext();
}
Run Code Online (Sandbox Code Playgroud)
您的所有客户来电都将从此开始.如果没有,请参阅文档.
现在,RF通过完全分离您想要从客户端(使用EntityProxy和ValueProxy)和服务器(真实对象,Entity值或简单DTO类)传递的对象来工作.您将在客户端/共享层中的任何位置使用代理类型(即,实现自动生成的接口),并且@ProxyFor仅在服务器端使用相对域对象(引用的对象).RF将负责其余部分.因此,您AdditionRequest将在您的服务器端,而AdditionRequestProxy将在您的客户端(请参阅中的说明RequestContext).另请注意,如果您只使用原始/盒装类型作为RequestContext参数或返回类型,则根本不需要创建ValueProxys,因为它们是默认可传输的.
你需要的最后一点是连接RequestFactoryServlet你的web.xml.请参阅此处的文档.请注意,如果您想要使用自定义ExceptionHandlers或ServiceLayerDecorators,您可以扩展它,但您不需要.
谈谈在哪里放一切:
Locators,ServiceLocators,服务实例,域对象和RequestFactoryServlet扩展,将在您的服务器端;RequestContext,RequestFactory扩展和所有代理的类型将是共用端;RequestFactory扩展并使用它来获取服务请求的工厂实例.总而言之......用RF创建一个简单的RPC机制,只需:
ServiceLocator;RequestContext为您的请求创建一个(使用服务和定位器值注释);RequestFactory扩展来返回你的RequestContext;RequestContext(如简单的DTOs)中使用多个原始类型,只需为它们创建客户端代理接口,注释@ProxyFor,并记住每种类型的使用位置;很像那样.好吧,我写的太多了,可能忘记了一些东西:)
供参考,请参阅:
[*]:在这种方法中,您将逻辑从面向数据的应用程序转移到面向服务的应用程序.当涉及到操作时,你放弃使用Entitys,IDs,versions,当然还有客户端和服务器之间的所有复杂差异逻辑CRUD.
| 归档时间: |
|
| 查看次数: |
1131 次 |
| 最近记录: |