Servlets是如何工作的?

3

我写了几个servlet程序,但我并不认为我完全理解servlet的运行方式。所以这里有几个问题:

我编写的所有Servlet代码都只能在安装了Apache Tomcat的Netbeans上运行。当我运行请求Servlet的html文件时,通常会出现找不到Servlet的错误,然后我就必须重新部署Servlet,然后一切都会正常运行。似乎我的Servlet在一段时间后会超时或者其他原因导致无法访问。

Servlet是否一直运行?Servlet具有init()和destroy()方法,因此我猜它不会一直运行。那么它何时开始运行,何时结束呢?当客户端发出请求时启动,超时时结束吗?如何解决我必须不断重新部署Servlet的问题。非常感谢。

4个回答

4
在正常情况下,一个servlet只有在关闭时(即应用程序容器如Tomcat关闭时)才会被销毁。否则,它将在应用程序运行期间一直保留在内存中。我无法确定你的Netbeans设置出了什么问题,但尝试将你的WAR文件部署到独立的Tomcat安装中,看看问题是否会消失。
应用程序容器还会在内存不足时调用destroy方法来销毁servlet,但这种情况很少发生。
关于你的请求问题,servlet被设计来处理多个请求。可以说servlet是应用程序范围的,而请求有自己的范围。

当你说要部署WAR文件到独立的Tomcat时,这意味着将WAR文件放置在Apache Tomcat文件夹中的webapps文件夹中。我理解正确吗?除此之外,您还需要做其他事情才能实际部署它,还是Tomcat会自动为您部署WAR文件? - Thang Pham
1
不需要,Tomcat会自动展开WAR文件。当你在webapps目录下看到一个与WAR文件同名的目录时,就表示已经成功展开了(例如,如果您部署了myapp.war,则会看到一个目录 $CATALINA_HOME/webapps/myapp/)。根据您所使用的Tomcat版本不同,您可能需要重启Tomcat,或者它会自动完成此操作。 - danben

2
你似乎正在使用Servlet开发。每当更改了web.xml或任何Servlet类时,你需要确保Web应用程序被完全发布。否则,你可能会冒着资源找不到的风险。
简单来说,“资源未找到”错误基本上就是“404页面未找到”错误。Servlet容器似乎无法找到与URL或url-pattern匹配的资源。就这样。
关于Servlet的生命周期,它只会在Web应用程序启动(发布、创建上下文)时创建一次,init()方法将被调用,并将实例保存在服务器的内存中,以类似于Map的方式。如果在您的Servlet中覆盖了init()方法,则会调用该方法。Servlet容器将为在web.xml中声明的所有servlet执行相同的操作(或根据Java EE 6中的注释@WebServlet)。
每当请求的URL与Servlet的url-pattern匹配时,都会调用(继承的)service()方法。通常的HttpServlet实现将根据HttpServletRequest#getMethod()确定要执行的方法。如果您在您的Servlet中覆盖了其中任何一个方法(doGet(),doPost()等),则将相应地调用它。
最后,在Web应用程序即将关闭(取消发布、销毁上下文)时,将为服务器内存中保存的任何Servlet实例调用destroy()。如果您在您的Servlet中覆盖了destroy()方法,则会调用它。

当你说“确保Web应用程序完全发布”时,是否只是指将更新的WAR文件复制到Tomcat中的webapp文件夹中? - Thang Pham
我不使用Netbeans,但在Eclipse中,您可以在服务器控制台中看到状态为“同步”。请查看Netbeans中是否存在类似的功能。 - BalusC

1
一个Servlet只有在被调用时才会“运行”。服务器将等待客户端的连接,读取头文件,在web.xml中查找正确的Servlet映射,然后调用该Servlet的service()方法。Servlet对象将一直保留在内存中,直到容器决定处理请求时将其释放(容器可以在任何时候释放它)。如果服务器决定释放特定的Servlet实例,则在下次请求该Servlet时将创建一个新的实例。
这意味着您不应该收到服务器无法找到您的Servlet的错误。假设应用程序已部署,并且存在正确的Servlet映射,则容器将能够处理请求。如果您编辑请求并粘贴完整的错误消息,有人可能会告诉您为什么没有发生这种情况。

谢谢!您的回复帮了我很多。我的servlet很少会关闭,如果它关闭了,我将尝试发布确切的错误信息。目前,我会尝试像其他人建议的那样,在独立的TOMCAT上部署WAR文件。 - Thang Pham

0

你需要研究Servlet的生命周期,这就是init()和destroy()方法存在的原因

通常情况下,init()方法只会在servlet第一次被调用时调用一次(除非你在Tomcat中设置了自动运行)

而当容器关闭时,destroy()方法会被调用

dopost()或doGet()方法(如果是HTTP servlet)则会在每个请求中被调用


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