gpt4 book ai didi

java - Tomcat 7 Servlet 产生一个线程

转载 作者:行者123 更新时间:2023-11-28 23:34:25 24 4
gpt4 key购买 nike

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

我在 Tomcat 中安装了 Apache FTPS 服务器,并准备好启动传输的 Java 客户端。

客户端将由 Servlet 调用。

例如:

http://laptop:8080/MyServlet?action=download&from=desktop&file=C:/home/fred/file.xml 

会告诉我的笔记本电脑上的实例从我的台式机下载file.xml

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

这个过程的两端都会有一个FTP服务器。 1 个在我的远程笔记本电脑上,1 个在我的本地桌面上。所以简而言之,我正在向远程端的 Servlet 提交一个 FTP“获取”请求。然后,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 中线程概念的新手,我总体上了解线程,因此感谢您能为我提供的任何帮助。

特雷弗

最佳答案

我不确定我是否真的理解你想要什么......

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 协议(protocol),并且能够使用它来下载文件。

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

根据评论编辑:

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

  • 按照您标签的建议,使用工作线程来完成这项工作。您的 servlet 是纯 Java,您可以像在任何其他 Java 应用程序中一样创建线程。如果您有兴趣稍后获得延迟处理的结果,您可以将 session (或简单地指向 session 属性)的引用提供给线程,它将能够放置其进度和/或完成状态。这需要更多样板代码,但保证可以工作(下面的示例)
  • 您可以在 servlet 返回之前关闭 HTTP 连接。官方 servlet 规范并未明确保证它,但我发现它至少可以在 tomcat 7 中工作。您可以在另一篇文章中找到更多详细信息 Servlet - close connection but not method

使用简单线程并在 session 中存储状态的示例:

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);
}
}
}

关于java - Tomcat 7 Servlet 产生一个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25931940/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com