前言
Servlet无疑是JavaWeb基础中的重要组成部分,我们需要借助Servlet来实现来自客户端的请求响应,借助Servlet来读取文件配置信息和初始化各类配置。虽然现在SpringMVC已经帮我们对Servlet做出了封装,我们已经很少需要直接操作Servlet了,但是了解和掌握Servlet的运行机制和特点,对于JavaWeb的开发人员来说,还是十分有必要的。本篇文章将对Servlet的重要知识点和一小部分的源码进行讲解,希望能够给各位想要了解Servlet的读者一个参考。
一、什么是Servlet
Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。简单来说,可以理解为Servlet就是一个运行在Web服务器上,对路径正确的请求作出一定响应的程序。
这里提到了两个关键词,Web服务器和路径。
我们在中小型项目中,我们一般使用tomcat
作为Web服务器来部署我们的项目,当我们编写好所有Servlet后,我们就可以部署在tomcat上,让tomcat托管我们的Servlet
,响应用户的请求。路径的意思是,我们需要为每一个Servlet指定匹配的请求路径,比如给TestServlet
配置的映射路径为/aa
,那么只有请求路径为ip:端口/项目名/aa
的请求才会落到TestServlet
上进行处理。
二、创建Servlet的三种方式
方式一:实现Servlet接口,很少用。
这种方式需要自己实现接口下的五个方法。一般来说的话,我们需要用到的方法只有service
一个方法就行。所以一般我们不使用这种方式
public class TestServlet implements Servlet {
public void init(ServletConfig servletConfig) throws ServletException {
}
public ServletConfig getServletConfig() {
return null;
}
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
public String getServletInfo() {
return null;
}
public void destroy() {
}
}
方式二:继承GenericServlet 抽象类,少用。
这种方法比方式一要好得多,我们只需要实现一个servicve方法即可。但GenericServlet
类只是简单地帮我们做了接口的空实现,没有做一些方法的封装,所以这种方式我们平时也比较少用。
public class TestServlet extends GenericServlet {
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
}
方式三:继承HttpServlet 类,常用
方式三是我们工作中用得最多的一种方式,HttpServlet
类继承了方式二中的GenericServlet
抽象类,同时HttpServlet作为专门处理Http请求的Servlet
,它还在类中进行了一定的逻辑封装,方便我们进一步的使用。一般来说,我们继承HTTPServlet后,会根据需要重写其中的doGet
和doPost
方法,来分别处理用户的get和post请求。
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
三、Servlet的使用和生命周期
(一)Servlet的使用
要想使用Servlet,我们需要先在web.xml
中对Servlet进行配置。
<!-- 配置servlet -->
<servlet>
<servlet-name>testServlet</servlet-name>
<servlet-class>com.xiaoming.web.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>testServlet</servlet-name>
<url-pattern>/aa</url-pattern>
</servlet-mapping>
servlet-mapping
表示由该Servlet响应的请求格式
servlet-class
表示处理请求的Servlet具体类
(二)Servlet的生命周期
Servlet的生命周期无非就是三点:
1. Servlet是什么时候被创建的
2. Servlet创建好后,是怎么响应用户的请求的
3. Servlet是什么时候被销毁的
了解了这三个问题后,想必大家会对Servlet有更深的了解。下面就来看一下答案吧
Servlet的创建
Servlet默认是在第一次接受请求的时候创建的,初始化过程中会执行init
方法。init方法只会执行一次
public class TestServlet extends HttpServlet {
@Override
public void init() throws ServletException {
System.out.println("init 方法被调用了...");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet 方法被调用了...");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost 方法被调用了...");
}
}
init方法演示用例
我们有时候会在init方法中做一些初始化的操作,当遇到比较耗时的初始化操作时,如果用户是第一次访问就可能要等好一会才有结果,这样很明显是对用户来说不太友好的。所以我们常常会将Servlet的初始化方法提前,在项目启动的时候就开始执行。提前的方法也很简单,只需要在web.xml
配置中改一下Servlet的load-on-startup
配置,修改加载顺序即可。一般来说数字越小,加载的优先级就越高。(但不能小于0)
<!-- 配置servlet -->
<servlet>
<servlet-name>testServlet</servlet-name>
<servlet-class>com.xiaoming.web.TestServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>testServlet</servlet-name>
<url-pattern>/aa</url-pattern>
</servlet-mapping>
Servlet的自调用
当Servlet接收到请求的时候,会调用service
方法进行处理。但是我们的业务逻辑一般并不是直接写在子类的service方法中,而是选择重写它的doGet
,doPost
方法。同时,service方法会在每次请求的时候调用一次。
Servlet的销毁
Servlet的销毁和初始化一样,只会进行一次,当web服务器移除项目或者是停止项目运行的时候
public class TestServlet extends HttpServlet {
@Override
public void destroy() {
System.out.println("destroy方法被调用了...");
}
Servlet销毁演示
四、ServletConfig的使用
我们有时候会需要在定义Servlet的时候,获取Servlet配置中的初始化参数。
初始化参数常常定义在web.xml文件中的init-param
标签中
<!-- 配置servlet -->
<servlet>
<servlet-name>testServlet</servlet-name>
<servlet-class>com.xiaoming.web.TestServlet</servlet-class>
<init-param>
<param-name>name</param-name>
<param-value>xiaoming</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>testServlet</servlet-name>
<url-pattern>/aa</url-pattern>
</servlet-mapping>
我们可以通过getServletConfig
得到我们配置的Servlet初始化参数。
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletConfig servletConfig = getServletConfig();
Enumeration<String> initParameterNames = servletConfig.getInitParameterNames();
while (initParameterNames.hasMoreElements()){
String elementKey = initParameterNames.nextElement();
System.out.println(elementKey + " = " +servletConfig.getInitParameter(elementKey));
}
System.out.println("doGet 方法被调用了...");
}
这种配置相对来说我们使用的会比较少,使用到的场景主要有项目中的某个模块的功能是第三方开发的,由于没有源码,需要我们在web.xml文件中配置参数,从而实现参数的传递。
网友评论