首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Tomcat 7 Servlet生成线程

Tomcat 7 Servlet生成线程
EN

Stack Overflow用户
提问于 2014-09-19 10:35:06
回答 1查看 591关注 0票数 0

我正在编写一个web应用程序,我想使用它来执行FTP任务(下载)

我已经在Tomcat和Java客户机中安装了Apache服务器,可以启动这些传输。

客户端将由Servlet调用。

例如:

代码语言:javascript
复制
http://laptop:8080/MyServlet?action=download&from=desktop&file=C:/home/fred/file.xml 

会告诉我的膝上型计算机上的实例从桌面下载file.xml

编辑:抱歉,我从来没有说得很清楚.

在这个进程的两端都会有一个FTP服务器。一个在我的远程笔记本电脑和一个在我的本地台式机。因此,简单地说,我正在向远程的Servlet提交一个FTP 'get‘请求。然后Servlet启动一个FTP进程,将文件拖过.

我的Servlet都被设置为接收GET参数并完成工作。

如果文件很大,那么每个请求都需要很长时间才能完成。我希望尽快释放Servlet资源。

理想情况下,我希望发生以下情况:

  1. 用户将URL发送到Servlet
  2. Servlet用来消化URL并计算出哪个文件以及从哪里来等.
  3. 将信息传递给线程的Servlet
  4. Servlet将带一条“进行中”消息返回
  5. 请求完成
  6. 线程仍然在后台工作,下载文件。

此时,我并不太关心Servlet是否了解线程的成功,我只是需要它来启动一个,然后忘记它。FTP进程将在其他地方对任何问题进行单独的日志记录。

我对在WebApp中创建线程池并从中获取线程的概念很感兴趣,但我发现的所有示例都很陈旧,并不能真正满足我的理解水平。

在StackOverflow上有一些类似的问题,这是我所要求的最相似的问题,但它只是暗示了一些我以前不知道的ExecutorService。我如何在WebApp?What is recommended way for spawning threads from a servlet in Tomcat中设置这个?

对于信息,我已经研究了这一点,并发现了许多不完整的例子,需要一个比我现在更好的理解,或提示什么是必要的。还有很多我读过的例子都是几年前的,不是最近的。我希望有一个神奇的一条线来做我需要的一切(可疑的),在过去的一年左右:)我是新的线程概念的Java,我了解线程在一般情况下,所以感谢任何帮助,您可以提供我。

特雷弗

EN

回答 1

Stack Overflow用户

发布于 2014-09-19 13:13:02

我不确定我真的明白你想要什么..。

代码语言:javascript
复制
client                                      server
send request (via HTTP) and wait for
         HTTP response
                                            analyse request and find file to send
                                            ... (processing)
                                            send HTTP response (1) with ?
opens FTP connection (could not open it before)
                                            receive FTP request (command connection)
                                            send file (data connection)
file is received and saved locally

如果客户端是浏览器,那么响应(1)应该足够重定向到像ftp://host/path/to/file这样的URL,因为所有主要的浏览器都知道FTP协议,并且能够使用它下载文件。

问题不在服务器端,您可以很容易地生成一个可以充当FTP客户端或(可能更难)充当FTP服务器的线程,但我无法想象客户端的重定向更好:客户端已经打开了HTTP连接,而不能用于FTP传输,而且必须为FTP请求打开一个新连接。由于它是一个新连接,您希望如何由在前一步启动的线程处理它?FTP中没有会话的概念,也没有简单的方法来确定正确的请求。

按评论编辑:

好的,看来您只是想在请求完成后在服务器上进行延迟处理。你有两种方法可以做到:

  • 正如您的标记所建议的,使用工作线程来完成这项工作。您的servlet是普通Java,您可以像在任何其他Java应用程序中一样创建一个线程。如果您有兴趣稍后获得延迟处理的结果,则可以将会话(或简单地指向会话属性)引用到线程,在该线程中,它将能够将其推进和/或完成状态置于其中。这需要更多的锅炉板代码,但保证能工作(下面的例子)
  • 您可以在servlet返回之前关闭HTTP连接。官方servlet规范没有提供明确的保证,但我发现它至少在tomcat 7中起作用。

示例使用简单线程,并将状态存储在会话中:

代码语言:javascript
复制
public class ThreadedServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest hsr, HttpServletResponse hsr1) throws ServletException, IOException {
        String fileName = null;
        // preliminary work ...
        Worker worker = new Worker(fileName);
        final HttpSession session = hsr.getSession();
        synchronized (session) {
            List<Status> statuses = (List<Status>) session.getAttribute("statuses");
            if (statuses == null) {
                statuses = new ArrayList<Status>();
            }
            statuses.add(new Status(fileName));
        }
        Thread thr = new Thread(worker);
        thr.start();
        // write the response either directly or by forwarding to a JSP
    }

    public static class Status implements Serializable {
        private String fileName;
        private WStatus status;

        public Status(String fileName) {
            this.fileName = fileName;
        }

        public String getFileName() {
            return fileName;
        }

        public void setFileName(String fileName) {
            this.fileName = fileName;
        }

        public WStatus getStatus() {
            return status;
        }

        public void setStatus(WStatus status) {
            this.status = status;
        }
    }

    public enum WStatus {
        STARTED,
        RUNNING,
        COMPLETED
    }

    private static class Worker implements Runnable {

        private String fileName;
        private Status status;

        public Worker(String fileName) {
            this.fileName = fileName;
        }

        @Override
        public void run() {
            status.setStatus(WStatus.RUNNING);
            // do your stuff ...
            status.setStatus(WStatus.COMPLETED);
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25931940

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档