簡體   English   中英

如何正確中斷JAX-RS AJAX請求

[英]How to properly interrupt JAX-RS AJAX request

我有一個部署到JBoss 7.1.1.Final的Java EE應用程序。 該應用程序利用JAX-RS為客戶端提供REST服務。 其中一個服務保持客戶端連接,直到通過BlockingQueue接收響應對象。 到目前為止,這似乎工作正常。 但是,即使刪除了應用程序部署/關閉了應用程序,連接也會保持打開狀態。 它甚至可以阻止JBoss關閉。

所以我試圖通過@PreDestroy回調中斷等待線程來執行干凈關閉。 該服務看起來像這樣:

@Path("/mypath")
@SessionScoped
public class MyResource implements Serializable {
  private static final long serialVersionUID = 1L;

  @Inject
  private EntityManager em;

  private Thread thread = null;

  @GET
  @Path("/{id:[0-9][0-9]*}")
  @Produces({
    MediaType.TEXT_PLAIN,
    MediaType.TEXT_XML
  })
  public Response getObjects(@PathParam("id") long id) {
    MyGroup group = this.em.find(MyGroup.class, id);
    if (group == null) {
      return Response.status(Status.NOT_FOUND)
          .entity("Group not found\n")
          .build();
    }

    if (group.isEmpty()) {
      return Response.status(Status.PRECONDITION_FAILED)
          .entity("Group is empty\n")
          .build();
    }

    BlockingQueue<?> queue = ... // Get queue for group

    this.thread = Thread.currentThread();
    try {
      MyObject object = queue.take();
    } catch (InterruptedException e) {
      return Response.noContent().build();
    }

    return Response.ok(object)
        .type(MediaType.TEXT_XML)
        .build();
  }

  @PreDestroy
  public void shutdown() {
    if (this.thread != null) {
      this.thread.interrupt();
    }
  }
}

它似乎有效,有點......客戶收到預期的響應。 但是,JBoss打印此異常:

13:38:44,489 ERROR [org.jboss.as.txn] JBAS010151: Unable to get transaction state: java.lang.IllegalStateException
    at org.jboss.msc.value.InjectedValue.getValue(InjectedValue.java:47)
    at org.jboss.as.txn.deployment.TransactionRollbackSetupAction.teardown(TransactionRollbackSetupAction.java:43)
    at org.jboss.as.web.ThreadSetupBindingListener.unbind(ThreadSetupBindingListener.java:61) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:195) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:]
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:]
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:]
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:]
    at java.lang.Thread.run(Thread.java:636) [rt.jar:1.6.0_18]

13:38:44,492 ERROR [org.apache.catalina.connector.CoyoteAdapter] An exception or error occurred in the container during the request processing: java.lang.RuntimeException: java.lang.IllegalStateException
    at org.jboss.as.web.ThreadSetupBindingListener.unbind(ThreadSetupBindingListener.java:67) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:195) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:]
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:]
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:]
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:]
    at java.lang.Thread.run(Thread.java:636) [rt.jar:1.6.0_18]
Caused by: java.lang.IllegalStateException
    at org.jboss.msc.value.InjectedValue.getValue(InjectedValue.java:47)
    at org.jboss.as.connector.deployers.processors.CachedConnectionManagerSetupProcessor$CachedConnectionManagerSetupAction.teardown(CachedConnectionManagerSetupProcessor.java:83)
    at org.jboss.as.web.ThreadSetupBindingListener.unbind(ThreadSetupBindingListener.java:61) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
    ... 8 more

那感覺不對勁。 中斷這種等待請求的正確方法是什么?

您正在中斷由容器創建的線程,因此容器無法完成線程本身。 您可以使用狀態變量來檢查線程是否應該結束,而不是中斷,例如(將其解釋為偽代碼):

while( ! stopped ) {
    MyObject object = queue.poll(25, TimeUnit.MILLISECONDS);

    return Response.ok(object)
        .type(MediaType.TEXT_XML)
        .build();
}

return Response.noContent().build();

並在@PreDestroy中將stopped設置為true 還有AsyncResponse功能。 您可以將所有打開的請求存儲在列表中,然后在@PreDestroy取消它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM