尽管网上有很多研究,但我无法找到解决问题的方法。 我想从GUI调用一个服务。该服务(Rest方法)使用线程启动异步处理。我希望服务立即给出对GUI的响应,以便不阻止GUI。在线程结束时,服务应该给出第二个响应,指示GUI已完成处理。
我想做的事情似乎与Reasteasy的异步HTTP部分相对应。所以,我已经尝试过这段代码(我只考虑了我的问题的重要部分):
@PUT
@Path("/duplicate/1")
public void duplicate( UcModel uc,
final @Suspend(TIMEOUT_ASYNCHRONOUS_DUPLICATION) AsynchronousResponse response) throws BusinessException {
Thread t = new Thread() {
@Override
public void run() {
try {
Thread.sleep(40000);
} catch (InterruptedException e) {
}
Response jaxrs = Response.ok(result).build();
response.setResponse(jaxrs);
}
};
t.start();
}
}
在我的web.xml中,我已经放了这段代码:
<servlet>
<servlet-name>resteasy-servlet</servlet-name>
<servlet-class>
org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher
</servlet-class>
<async-supported>true</async-supported>
</servlet>
问题是:Web服务不会立即给出响应。它仅在线程结束时给出响应,并且GUI被阻止。 通过查看代码,我甚至不理解服务如何立即给出“无效”结果的响应。
有关信息:Web服务的调用是在一个Javascript框架ExtJS中进行的。它执行Ajax请求。
如果有人可以帮我解决这个问题,那将会很棒。提前致谢
塞德里克
答案 0 :(得分:5)
您应该使用两个不同的Web服务来解决此问题。
AsynchronousResponse
主要用于帮助服务器线程池性能,而不是用于客户端。
服务器在线程池中具有有限数量的线程,可以满足客户端的请求,并且在AsynchronousResponse
的帮助下,您可以将耗时的作业放在后台线程中。
客户端必须等待异步进程完成或超时。只有在那之后才会提交响应,因此对于客户端来说,完成请求几乎需要相同的时间。
其他选择是尝试ChunkedOutput
可以找到here的java类。
这是用于以“键入的”块发送消息。适用于长时间运行的流程,需要产生部分响应。
一个例子:
@Path("/test")
public class TestResource {
@GET
public ChunkedOutput getTestResponse() {
final ChunkedOutput chunkedOutputs = new ChunkedOutput(String.class);
new Thread() {
public void run() {
try {
while (hasNextValue()) {
chunkedOutputs.write(getNextLongRunningOperationValue());
}
} catch (IOException e) {
(...)
} finally {
chunkedOutputs.close();
}
}
}.start();
//the chunkedOutputs will be probably returned even before a first value is written by the new thread
return chunkedOutputs;
}
private boolean hasNextValue() {
(...)
}
private String getNextLongRunningOperationValue() {
(...) //this takes a lot of time, so it's time for a coffee :)
}
}