Servlet 接口定义的5个抽象方法
void init(ServletConfig config) // 容器创建好对象Servlet对象后就会调用此方法,通过ServletConfig对象传递初始化配置信息
ServletConfig getServletConfig() // 返回Servlet的ServletConfig对象
String getServletinfo() // 返回关于Servlet的信息,例如,作者,版本和版本等信息
void service(ServletRequest request, ServeltResponse response) // 负责响应用户的请求
void destroy() // 负责释放Servlet对象占用的资源
Servlet 类的继承体系
Servlet 的生命周期
1、执行 Servlet 构造器方法
2、执行 init 初始化方法
第一、二步,是在第一次访问的时候创建 Servlet 程序会调用。
3、执行 service() -> 根据请求调用 doGet() doPost() 方法
第三步,每次访问都会调用。
4、执行 destroy 销毁方法
第四步,在 web 工程停止的时候调用。
xml文件的配置
进入WEB-INF,编写一个web.xml文件,编写配置信息
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--servlet标签给Tomcat配置Servlet程序-->
<servlet>
<!--给Servlet程序起一个别名(一般是类名)-->
<servlet-name>HelloServlet</servlet-name>
<!--是Servlet程序的全类名-->
<servlet-class>com.servlet.HelloServlet</servlet-class>
</servlet>
<!--给Servlet程序配置访问地址-->
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<!--注意要以 / 开头-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
Servlet 程序虚拟路径的映射
一个Servlet程序可以配置多个元素实现Servlet的多重映射,也可以在一个下配置多个子元素。
HttpServlet 类的部分源码
public abstract class HttpServlet extends GenericServlet {
private static final long serialVersionUID = 1L;
private static final String METHOD_GET = "GET";
private static final String METHOD_POST = "POST";
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_get_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(405, msg);
} else {
resp.sendError(400, msg);
}
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_post_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(405, msg);
} else {
resp.sendError(400, msg);
}
}
/**
根据请求方式的不同调用对应的do()方法来处理用户请求
*/
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);
}
}
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
HttpServletRequest request;
HttpServletResponse response;
try {
// 将HTTP请求和响应分别转换为对应的对象
request = (HttpServletRequest)req;
response = (HttpServletResponse)res;
} catch (ClassCastException var6) {
throw new ServletException("non-HTTP request or response");
}
this.service(request, response);
}
}
ServletConfig 类的使用
Servlet 程序的配置信息类,Servlet 程序默认是第一次访问的时候创建,ServletConfig 是每个 Servlet 程序创建时,就创建一个对应的 ServletConfig 对象。
注意:否则会空指针异常
在 web.xml 中的配置
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.atguigu.servlet.HelloServlet</servlet-class>
<!--init-param 是初始化参数 -->
<init-param>
<!-- 是参数名 -->
<param-name>username</param-name>
<!-- 是参数值 -->
<param-value>root</param-value>
</init-param>
<!--init-param 是初始化参数 -->
<init-param>
<!-- 是参数名 -->
<param-name>url</param-name>
<!-- 是参数值 -->
<param-value>jdbc:mysql://localhost:3306/test</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
ServletContext 接口的作用
1、获取 web.xml 中配置的上下文参数 context-param
web.xml 中的配置(属于整个 web 工程)
<!-- 在整个web容器中设置上下文初始化参数 -->
<context-param>
<param-name>username</param-name>
<param-value>context</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>root</param-value>
</context-param>
使用示例:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter pw = resp.getWriter();
resp.setContentType("text/html;charset=utf-8");
// 获取 ServletContext 对象
ServletContext servletContext = getServletConfig().getServletContext();
// 得到包含所有初始化参数名的 Enumeration 对象
Enumeration<String> paramNames = servletContext.getInitParameterNames();
// 遍历输出
while (paramNames.hasMoreElements()) {
String name = paramNames.nextElement();
String value = servletContext.getInitParameter(name);
pw.println(name + " " + value);
}
}
2、获取当前的工程路径,格式: /工程路径
servletContext.getContextPath() // /servlet
3、获取工程部署后在服务器硬盘上的绝对路径
// /斜杠被服务器解析地址为 :http://ip:port/ 工程名 / 映射到 IDEA 代码的web目录
String getRealPath(String path) // path 应该以 / 开头
InputStream getResourceAsStream(String path) // 读取资源文件
path = "/WEB-INF/classes/itcast.properties";
4、像 Map 一样存取数据
由于一个web应用中的所有Servlet共享同一个ServletContext对象,因此,ServletContext对象的域属性可以被该web应用中的所有Servlet访问
Enumeration getAttributeNames()
Object getAttribute(String name)
void removeAttribute(String name)
void setAttribute(String name, Object obj)
servlet3.0与2.5版本的区别
不需要在web.xml中配置,但需要在servlet类的定义处之上编写注解 @WebServlet(“url-pattern的值”)