我正在尝试设置一个servlet,我可以使用它来异步调用webservices。在大多数情况下,它工作正常。我有一个带有doGet方法的servlet和一个调用它的js。我在js中有一个回调方法,servlet在完成它的操作后正确调用。
复杂的是,我调用的其中一个Web服务也是异步的,我希望能够在异步ws回调完成后第二次调用js回调方法。例如,如果您有一个状态字段,当您调用同步Web服务时,它会立即更新为“Beginning Synchronous Call”,然后当servlet回调到达时,它将更改为回调值,这是Web服务的结果。
当您调用异步Web服务时,更新字段会立即更新为“Beginning Asynchronous Call”,并且很快会收到来自servlet的第一个回调,指示已经请求了Web服务,因此我们将该字段更新为“Processing Web”服务“或其他什么。问题是,一旦Web服务完成并回调到servlet,我似乎无法弄清楚如何将结果发送到js回调方法。
我是AJAX和servlets的新手,所以也许这是实现我想要的一种可怕方式。
Web服务都在Servlet中调用,主要使用Netbeans自动生成的WS调用。 WS调用自身工作正常,但是一旦我得到异步WS的结果,我就陷入了webservice回调的handleResponse方法,并且不再对我想要更新的文档的响应元素有任何引用。
我尝试将原始响应变量存储为静态成员变量,并在handleResponse方法中使用它,如下所示:
javax.xml.ws.AsyncHandler<WsClients.Op11Response> asyncHandler = new javax.xml.ws.AsyncHandler<WsClients.Op11Response>() {
public void handleResponse(javax.xml.ws.Response<WsClients.Op11Response> asyncResponse) {
try {
storedResponse.setContentType("text/xml");
String returnString = asyncResponse.get().getReturn();
storedResponse.getWriter().write("<returnData><content>"
+ returnString + "</content></returnData>");
} catch (Exception ex) {
}
}
};
这不会在附加调试器的情况下编译,并且似乎无法分配引用。
有更好的方法吗?
答案 0 :(得分:2)
HTTP的本质是您不能将任何内容发送回客户端,除非客户通过轮询或保持连接打开来请求此信息。
启动异步调用的操作立即结束,您需要从servlet doGet方法返回(虽然从技术上讲,您可以保持servlet调用,直到您的异步调用完成,我不建议这样做,因为它占用了服务器资源一般情况下,尽快从servlet返回是一种很好的做法。
最佳行动方案是:
如果您对上面的步骤3中的轮询实现感到满意,您可能需要考虑Comet, a.k.a. long poll来替换客户端轮询。
答案 1 :(得分:1)
Servlet无法再次发送响应。 HTTP协议是同步的,只有客户端才能发起请求 - 响应交换。
对于异步更新,您需要从客户端到服务器端执行轮询,并在服务器端(在会话中)累积消息,直到客户端选择它们或它们到期为止。