void init(ServletConfig config)
:初始化void service(ServletRequest request, ServletResponse response)
:服务 处理业务逻辑void destroy()
:销毁service
方法没有具体实现,其余都实现了空参的Init() 若我们自己想对servlet进行初始化操作,重写这个init()方法即可
init()
方法的源码
service
做了实现,把参数进行强制转换,调用了重载的service方法
重载的servide
方法获取请求的方式,根据请求的不同调用相应的doGet()/doPost()
方法
查看源码
public void service(ServletRequest req, ServletResponse res)
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
HttpServletRequest request;
HttpServletResponse response;
try {
//强转
request = (HttpServletRequest)req;
response = (HttpServletResponse)res;
} catch (ClassCastException var6) {
throw new ServletException("non-HTTP request or response");
}
//调用这个重载的方法
this.service(request, response);
}
-注意参数类型
service
protected void service(HttpServletRequest req, HttpServletResponse resp)
GET/POST
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getMethod();
long lastModified;
if (method.equals("GET")) {
lastModified = this.getLastModified(req);
if (lastModified == -1L) {
this.doGet(req, resp);
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader("If-Modified-Since");
} catch (IllegalArgumentException var9) {
ifModifiedSince = -1L;
}
if (ifModifiedSince < lastModified / 1000L * 1000L) {
this.maybeSetLastModified(resp, lastModified);
this.doGet(req, resp);
} else {
resp.setStatus(304);
}
}
} else if (method.equals("HEAD")) {
lastModified = this.getLastModified(req);
this.maybeSetLastModified(resp, lastModified);
this.doHead(req, resp);
} else if (method.equals("POST")) {
this.doPost(req, resp);
} else if (method.equals("PUT")) {
this.doPut(req, resp);
} else if (method.equals("DELETE")) {
this.doDelete(req, resp);
} else if (method.equals("OPTIONS")) {
this.doOptions(req, resp);
} else if (method.equals("TRACE")) {
this.doTrace(req, resp);
} else {
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[]{method};
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(501, errMsg);
}
}
定义一个类
LifeServlet
,继承Servlet
接口,实现init(),service(),destroy()
方法,来说明servlet的生命周期
LifeServlet
package com.zqx.c_life;
import javax.servlet.*;
import java.io.IOException;
/**
* 20190810
* 实现Servlet接口
* 说明 Servlet的生命周期
*/
public class LifeServlet implements Servlet {
/**
* 初始化方法
* 执行者:服务器
* 执行次数:一次
* 执行时机:默认第一次访问的时候
*/
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("5555555555555555");
}
/**
* 服务
* 执行者:服务器
* 执行次数:请求一次执行一次
* 执行时机:请求来的时候
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("666666666666666");
}
/**
* 销毁
* 执行者:服务器
* 执行次数:只执行一次
* 执行时机:当servlet被移除的时候或者服务器正常关闭的时候
*/
@Override
public void destroy() {
System.out.println("4444444444444444");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public String getServletInfo() {
return null;
}
}
<a href="/servlet/life?name=tom">生命周期a>
<servlet>
<servlet-name>LifeServletservlet-name>
<servlet-class>com.zqx.c_life.LifeServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>LifeServletservlet-name>
<url-pattern>/lifeurl-pattern>
servlet-mapping>
void init(ServletConfig config):初始化
默认
(说明可以自己设置)第一次访问的时候void service(ServletRequest request,ServletResponse response):服务 处理业务逻辑
void destroy():销毁
servlet是单线程多实例,默认第一次访问的时候,服务器创建servlet,并调用init方法实现初始化,并调用一次service方法, 每当有新的请求,服务器创建一个线程,调用service方法来执行自己的业务逻辑,当当serlvet被移除的时候服务器正常关闭的时候,服务器调用servlet的destroy方法实现销毁操作.
创建一个servlet后,这个servlet要被访问到,必须在web.xml中进行配置,其中有一个
的标签确定访问一个servlet的路径
<servlet>
<servlet-name>LifeServletservlet-name>
<servlet-class>com.zqx.c_life.LifeServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>LifeServletservlet-name>
<url-pattern>/lifeurl-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>LifeServletservlet-name>
<url-pattern>/life01url-pattern>
servlet-mapping>
com.zqx.c_life.LifeServlet
可以被路径/life
和/life01
访问到完全匹配:必须以”/”开始,例如: /hello /a/b/c
目录匹配:必须"/"开始 以"*"结束 例如: /a/* /*
后缀名匹配 以"*"开始 以字符结尾 例如: *.jsp *.do *.action
优先级:完全匹配>目录匹配>后缀名匹配
假设:
<servlet-mapping>
<servlet-name>jspservlet-name>
<url-pattern>*.jspurl-pattern>
<url-pattern>*.jspxurl-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>defaultservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
这时它的值就是”/”那么这时它就是一个默认(缺省)的servlet.。 默认的servlet其作用是用于处理其它的servlet处理不了的请求。
前面说到一个servlet的生命周期的时候,
init
方法的执行时间是默认
第一次访问的时候,通过对某个Servlet的配置,可以改变这个方法的执行时间
load-on-startup
是servlet标签下的一个子标签值越小优先级越高
<servlet>
<servlet-name>LifeServletservlet-name>
<servlet-class>com.zqx.c_life.LifeServletservlet-class>
<load-on-startup>3load-on-startup>
servlet>
LifeServlet
的init
方法就已经被调用了就是tomcat
服务器tomcat
服务器是如何完成这个响应的呢?tomcat/conf/web.xml
,发现有这一段配置信息: <servlet>
<servlet-name>defaultservlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServletservlet-class>
<init-param>
<param-name>debugparam-name>
<param-value>0param-value>
init-param>
<init-param>
<param-name>listingsparam-name>
<param-value>falseparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>defaultservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
会查找tomcat的web.xml
web.xml
和tomcat的web.xml
直接存在一种继承关系
,优先查找项目里的web.xml,如果没有找到,就会去tomcat的web.xml中查找
<welcome-file-list>
<welcome-file>index.htmlwelcome-file>
<welcome-file>index.htmwelcome-file>
<welcome-file>index.jspwelcome-file>
welcome-file-list>
./
或者 不写../
http://www.baidu.com
/servlet/hello
经常使用