Java 呼叫jersey服务(PUT)时发送电子邮件通知的设计问题

Java 呼叫jersey服务(PUT)时发送电子邮件通知的设计问题,java,web-services,design-patterns,jersey,Java,Web Services,Design Patterns,Jersey,我这里有一个设计问题。我有一个用实现的RESTful web服务。我还使用SpringMail发送电子邮件 我的规范需要通知某一组用户(大约15-20个)已发出PUT请求,并在修改资源时通知他们。我还需要向作为响应发出请求的客户端发送一个JSON数组 现在,我所做的是在修改了我的方法之后,我处理PUT服务,向用户发送电子邮件,然后返回JSON状态 但是为什么客户机要等待邮件通知完成呢?如果我的客户列表很长,而客户机等待很长时间才能得到响应呢。这不是他的头痛。但我也需要在PUT方法中通知用户。如果

我这里有一个设计问题。我有一个用实现的RESTful web服务。我还使用SpringMail发送电子邮件

我的规范需要通知某一组用户(大约15-20个)已发出PUT请求,并在修改资源时通知他们。我还需要向作为响应发出请求的客户端发送一个JSON数组

现在,我所做的是在修改了我的方法之后,我处理PUT服务,向用户发送电子邮件,然后返回JSON状态

但是为什么客户机要等待邮件通知完成呢?如果我的客户列表很长,而客户机等待很长时间才能得到响应呢。这不是他的头痛。但我也需要在PUT方法中通知用户。如果我返回JSON,我就失去了通过退出请求-响应周期来发送通知的上下文

有更好的方法吗

为了了解情况,我提供了代码的相关部分:

 //first notify users
 notifyUsers(event,jsonEntity,NotificationType.TicketType.UPDATED);

 //then return response  
 return new JSONObject()
            .put("response_code:", Response.status(Status.OK).build())
            .put("title", evento.getDescrizioneevento())
            .put("status", getEventAsString(evento.getStatoevento()))
            .put("solved", evento.getCausascatenante());
使“notifyUsers”异步

将请求排队,稍后再处理。您可以在单例中使用一个简单的BlockingQueue,让线程监听另一端,也可以设置一个更正式的队列系统,如JMS。您还可以将请求插入到数据库中,并在其中侦听活动

或者,您可以直接在那里启动一个简单的线程,并让它在您从请求返回时运行。这也行


各种各样的选择,各有利弊。

在我拥有web服务的类中,我有一个内部类,它将在单独的线程中执行

 class MailExecutorService implements Runnable {

    EventiAnomali eventiAnomali;
    JSONObject jsonEntity;
    NotificationType.TicketType type;

    public MailExecutorService(EventiAnomali eventiAnomali,JSONObject jsonEntity,
                               NotificationType.TicketType type) {
        this.eventiAnomali = eventiAnomali;
        this.jsonEntity =jsonEntity;
        this.type = type;
    }

    public void run() {
        notifyUsers(eventiAnomali,jsonEntity,type); // I've made notifyUser asynchronous
    }
}
在我使用的返回之前的@PUT方法中

 executorService.execute(
 new MailExecutorService(evento,jsonEntity,
       (evento.getStatoevento().equals("5"))? NotificationType.TicketType.CLOSED:
       NotificationType.TicketType.UPDATED));

 response = MY_JSON
我已经在我的
finally
块中放置了
executor.shotton()
。最后一行是返回的
JSON
(响应)


这些都可以吗?更不用说它能用了。

谢谢,我确实选择了你告诉我的一个选项。你能验证一下吗?我现在发布我的答案。不,这太好了。但是,您应该做的是将ExecutorService设置为单例,并使用Executors.newFixedThreadPool(xxx)。在ServletContextListener中的容器启动时执行此操作。您希望这样做的原因是,您可以承受流量风暴,并继续向执行器提交请求,但它只会同时运行xxx线程,最终消耗所有请求。然后在您的ContextListener中,您可以在关闭容器并等待其完成时关闭ExecutorService,这样在重新启动时不会丢失电子邮件。