目录
6.1 部署Servlet
部署Servlet是指将编译好的Servlet类文件及其配置信息放入Web应用程序的正确结构中,然后将整个Web应用部署到支持Servlet技术的服务器上。具体步骤如下:
-
构建Web应用结构:根据Java Web应用的标准目录结构,创建
WEB-INF
目录,并在其中放置一个web.xml
部署描述符文件(对于使用注解配置的Servlet,此步骤非必须)。 -
放置Servlet类文件:将编译后的Servlet
.class
文件放在Web应用的某个包路径下,并将其包含在Web应用的CLASSPATH中。例如,在WEB-INF/classes/com/example/servlet
目录下存放Servlet类。 -
配置Servlet:在
web.xml
中声明并映射Servlet,或者使用Servlet 3.0及更高版本的注解进行配置。 -
打包部署:将Web应用的所有内容打包成WAR(Web ARchive)文件,然后将WAR文件部署到Servlet容器(如Tomcat、Jetty等)的相应位置,通过容器的管理界面或命令行工具启动Web应用。
6.2 请求Servlet
请求Servlet是通过发送HTTP请求到其对应的URL映射地址来实现的。当用户访问这个URL时,Servlet容器会解析请求并找到匹配的Servlet进行处理。例如,如果一个Servlet映射为/myServlet
,则可以通过浏览器访问http://yourserver.com/yourappcontext/myServlet
来请求该Servlet。
对Servlet的访问与对JSP的访问基本相同,可以通过以下3种方式进行:
- 通过在浏览器中直接输入地址访问
http://127.0.0.1:8080/test/hello
或http://localhost:8080/test/hello
- 通过超链的形式访问
<a href =“http://127.0.0.1:8080/test/hello
”>第一个Servlet</a>
- 通过表单提交的方式访问
<form method=get
action="http://127.0.0.1:8080/test/hello">
6.3 找不到servlet包
找不到Servlet包通常是因为以下原因之一:
- 编译问题:Servlet类没有被正确编译,导致
.class
文件不存在。 - 部署问题:Servlet的
.class
文件未放置在正确的Web应用目录结构下的CLASSPATH内,即未存放在WEB-INF/classes
目录或其子包内。 - 配置问题:在
web.xml
中没有正确配置Servlet的名称和类名,或者注解配置不正确,导致容器无法识别并加载Servlet。 - 依赖缺失:Servlet需要的外部库或依赖未添加至项目的类路径中,使得Servlet不能正常工作。
6.4 Servlet映射的细节
Servlet映射是指将特定的URL模式与Servlet关联起来的过程,这样当客户端请求符合该URL模式的资源时,Servlet容器就会调用相应的Servlet来处理请求。
XML配置方式(web.xml)
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.example.MyServletClass</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/myservlet/*</url-pattern>
<!-- 或 -->
<url-pattern>/myservlet</url-pattern>
</servlet-mapping>
上述配置将Servlet类com.example.MyServletClass
映射到了以/myservlet
开头的URL上。
注解配置方式(Servlet 3.0+)
@WebServlet("/myservlet")
public class MyServlet extends HttpServlet {
// ...
}
上述代码使用了@WebServlet
注解直接将Servlet映射到/myservlet
URL。
Servlet映射细节包括:
- 精确匹配:如果URL模式没有通配符
*
,那么只有完全匹配的URL才能触发Servlet。 - 路径匹配:使用
/*
表示根路径下的所有资源;使用/path/*
可以匹配以/path
开始的任意后续路径。 - 默认Servlet:仅包含
/
的URL模式通常用于定义默认Servlet,它负责处理未被其他Servlet映射覆盖的所有请求。 - 优先级:如果有多个Servlet映射匹配同一个URL,Servlet容器会选择第一个匹配项进行处理,因此在配置时需要注意映射顺序。
6.5 Servlet生命周期
Servlet的生命周期包含以下几个阶段:
-
实例化:当Web容器首次接收到针对Servlet的请求时,如果该Servlet还没有实例化,则会根据Servlet类创建一个Servlet实例。也可以通过在
web.xml
中设置<load-on-startup>
标签或使用@WebServlet
注解中的loadOnStartup
属性指定Servlet是否在应用启动时就加载和实例化。 -
初始化:在Servlet实例化后,容器调用其
init()
方法进行初始化。通常情况下,开发者可以重写这个方法来执行一次性配置操作,如数据库连接初始化、读取配置文件等。参数可以通过实现javax.servlet.ServletConfig
接口的对象传递给Servlet。
@Override
public void init(ServletConfig config) throws ServletException {
// 初始化工作
}
-
服务请求:每当接收到一个HTTP请求且URL映射到此Servlet时,容器就会创建一个新的请求(HttpServletRequest)和响应(HttpServletResponse)对象,并调用Servlet的
service()
方法。service()
方法会根据请求类型(GET、POST等)调用相应的doGet()、doPost()等方法处理请求。 -
销毁:当Web容器关闭或者卸载Servlet时,会调用Servlet的
destroy()
方法。在此方法中,开发者可以释放资源,例如关闭数据库连接等。
@Override
public void destroy() {
// 清理和资源释放工作
}
6.6 多线程与并发处理
Servlet是多线程安全的,这意味着多个用户同时请求同一个Servlet时,Web容器会为每个请求分配一个新的线程来执行Servlet的service()
方法。因此,在编写Servlet代码时,需要注意避免共享可变数据导致的竞争条件问题,确保状态变量的线程安全性。另外,对于那些需要长时间运行的任务,建议将它们放在后台线程中,以免阻塞Servlet线程影响其他用户的请求处理。
6.7 Servlet过滤器与监听器
-
Servlet过滤器(Filter):用于对进入Servlet的HTTP请求或从Servlet发出的HTTP响应进行预处理或后处理。它可以用来做身份验证、日志记录、内容压缩等功能。
-
Servlet监听器(Listener):监听Web应用程序中的特定事件,如Servlet上下文的初始化和销毁、会话创建和失效、属性绑定和解除绑定等。监听器可以在这些事件发生时执行相应的操作,帮助管理应用的状态和行为。
总之,Servlet作为Java Web开发的核心组件之一,它的正确理解和高效利用有助于构建高性能、可维护的企业级Web应用程序。而了解并掌握Servlet的生命周期、多线程处理以及过滤器和监听器的使用,对于提升Java Web开发技能至关重要。