Servlet中的后台进程

5

有没有可能在servlet中实现后台进程!?

让我解释一下。 我有一个servlet,它显示一些数据并生成一些报告。 生成报告意味着数据已经存在,并且是这样的:其他人上传了这些数据。

除了报告生成之外,我还应该实现一种在新数据(已上传)到达时发送电子邮件的方法。

2个回答

19

该功能需求不明确,但是为了回答实际问题:是的,在servlet容器中运行后台进程是可能的。

如果您想要一个应用程序范围的后台线程,请使用ServletContextListener来挂接Web应用程序的启动和关闭,并使用ExecutorService来运行它。

@WebListener
public class Config implements ServletContextListener {

    private ExecutorService executor;

    public void contextInitialized(ServletContextEvent event) {
        executor = Executors.newSingleThreadExecutor();
        executor.submit(new Task()); // Task should implement Runnable.
    }

    public void contextDestroyed(ServletContextEvent event) {
        executor.shutdown();
    }

}

如果您还未使用Servlet 3.0,因此无法使用@WebListener,请改为在web.xml中按如下方式注册:

<listener>
    <listener-class>com.example.Config</listener-class>
</listener>
如果您想要一个会话范围内的后台线程,请使用HttpSessionBindingListener来启动和停止它。
public class Task extends Thread implements HttpSessionBindingListener {

    public void run() {
        while (true) {
            someHeavyStuff();
            if (isInterrupted()) return;
        }
    }

    public void valueBound(HttpSessionBindingEvent event) {
        start(); // Will instantly be started when doing session.setAttribute("task", new Task());
    }

    public void valueUnbound(HttpSessionBindingEvent event) {
        interrupt(); // Will signal interrupt when session expires.
    }

}

在第一次创建和启动时,只需执行

request.getSession().setAttribute("task", new Task());

谢谢您的回复。抱歉,我的请求是要实现一种发送电子邮件(警报)的方式,当上传了一些数据时(数据库中加载了新数据)。我曾考虑通过修改现有的Web应用程序来实现这个机制,创建一个后台进程来轮询新数据。这些数据是由我无法管理的其他应用程序加载的。Servlet容器是Tomcat。感谢您的答复。 - sangi
为什么不直接在更新数据库中的数据的代码后面添加这段代码呢? - BalusC
因为我无法访问加载数据的应用程序:它由其他人管理和开发,我无法联系到他们。 - sangi
这个线程没有阻塞,对吧? - Thomas

0

谢谢!我在想这个最好是在请求范围内完成,比如:

public class StartServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {                   
        request.getSession().setAttribute("task", new Task());     
    }
}

这样,当用户离开页面时,进程就会停止。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接