Servlet 2.x 规范
sun 公司制订的一种用来扩展 web 服务器功能的组件规范。
Servlet 接口
:init(ServletConfig config)、service(ServletRequest req, ServletResponse res)、destroy()GenericServlet 抽象类
:实现了 Servlet 接口中的 init, destroy 方法HttpServlet 抽象类
:继承了 GenericServlet 抽象类,实现了 service()ServletConfig 接口
:String getInitParameter(String paraName)ServletRequest 接口
:HttpServletRequest 的父接口ServletResponse 接口
:HttpServletResponse 的父接口
一、Servlet
1.1 Servlet 的生命周期
Servlet 的生命周期指 Servlet 容器如何去创建 Servlet 对象、如何给 Servlet 对象分配资源、如何调用 Servlet 对象的方法来处理请求、以及如何销毁 Servlet 对象的整个过程。
Servlet 生命周期的四个阶段:
(1) 实例化:容器调用 Servlet 的构造器,创建 Servlet 对象。
情况1:容器收到请求后才创建 Servlet 对象。默认,容器只会为 Servlet 创建唯一一个实例。
情况2: 容器启动时交某些 Servlet 对象创建好(需要配置 load-on-startup)。load-on-startup 参数值必须是 >=0 的整数,越小优先级(即先实例化)越高。
(2) 初始化:容器在创建好 Servlet 对象后,立即调用 init() 方法。
init() 只执行一次
GenericServlet 已经实现了 init(),该方法会将容器创建好的 ServletConfig 对象作为参数传给 init()。
ServletConfig 对象提供一个 getInitParameter() 来访问 Servlet 的初始化参数。
如果 GenericServlet 的 init() 提供的初始化操作不满足需要,可以重写 init() 无参方法,不重写 init(ServletConfig config)
(3) 就绪
Servlet 对象可以调用了,容器收到请求后,会调用 Servlet 对象的 service() ,该方法会依据请求类型(get/post)分别调用 doGet(), doPost()
(4) 销毁:Servlet 容器在销毁 Servlet 对象之前,会调用 destroy() 方法。
1.2 Servlet 如何处理请求资源路径
Servlet 容器会先假设访问的是一个 Servlet ,会依据应用名(appname)找到应用所在的文件夹,然后找到 web.xml 文件。
匹配
- 精确匹配(完全匹配)
- 通配符匹配:使用 * 匹配任意长度的字符串。eg:
- 后缀匹配:使用 . 开头,后面可以接任意字符。eg: .do
如果都不匹配,则容器认为访问的是一个静态资源文件(html/css/js),如果找到则返回,否则返回404。
1.3 Servlet 是如何运行的?
- 浏览器依据 ip, port 建立与 Servlet 容器之间的连接。
- 浏览器将请求数据打包(即按照 http 协议的要求,将相关数据封闭成一个数据包,即请求数据包)并发送给 Servlet 容器。
- Servlet 容器解析请求数据包,并将解析后的数据放到 request 对象上。同时创建一个 response 对象。
- Servlet 容器依据请求资源路径找到 Servlet 的配置,然后创建 Servlet 对象。
- Servlet 调用 service 方法,并且会将事先创建好的 request 对象和 response 对象作为 service 方法的参数传递给 Servlet 对象。
- Servlet 通过 request 对象获得请求参数,进行相应的处理,然后将处理结果写到 response 对象上。
- Servlet 读取 response 对象上的数据,然后将处理结果打包(响应数据包)并发送给浏览器。
- 浏览器解析响应数据包,将返回的数据展现给用户。
1.4 实例
public class HelloWorldServlet extends HttpServlet {
public void service(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
//1、读请求参数值
String qtyStr = req.getParameter("qty");
int qty = Integer.parseInt(qtyStr);
//2、处理请求
String rs = "";
for (int i = 0; i < qty; i++) {
rs += "<h1>Hello World</h1>";
}
//3、设置一个消息头content-type,告诉浏览器返回的数据类型是一个html文档及编码格式
//告诉服务器使用out输出时使用指定的编码格式进行编码
res.setContentType("text/html;charset=utf-8");
//4、获得一个输出流
PrintWriter out = res.getWriter();
//5、调用流的方法进行输出,其实质是将处理结果写到了res对象上
out.println(rs);
out.close();
}
}
配置 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_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>helloWord</servlet-name>
<!--类名要完整(包名,类名都要全)-->
<servlet-class>com.herolei.HelloWorldServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>helloWord</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
启动程序,访问 http://localhost:8080/hello?qty=30
补充:web 打包后的目录如下
appname(应用名)
└──WEB-INF
├──classes .class文件
├──lib .jar文件,lib文件夹可选
└──web.xml 部署描述文件
二、Listener
Servlet 规范当中定义的一种特殊的组件,用来监听容器产生的事件并进行处理。
容器会产生两大类事件:
- 生命周期相关的事件:容器在创建或者销毁 request, servletContext(Servlet 上下文)时产生的事件。对应的接口有 ServletRequestListener、ServletContextListener。
- 绑定相关的事件:容器调用了 request, servletContext 的 setAttribute, removeAttribute 时产生的事件。。对应的接口有 ServletContextAttributeListener、ServletRequestAttributeListener。
public interface ServletContextListener extends EventListener {
// 容器初始化
void contextInitialized(ServletContextEvent ctx);
// 容器销毁
void contextDestroyed(ServletContextEvent ctx);
}
public interface ServletContextAttributeListener extends EventListener {
void attributeAdded(ServletContextAttributeEvent event);
void attributeRemoved(ServletContextAttributeEvent event);
void attributeReplaced(ServletContextAttributeEvent event);
}
三、Filter
public interface Filter {
// 初始化 Filter
void init(FilterConfig filterConfig) throws ServletException;
// 调用,如果要继续调用下一个 Filter,需要调用 chain.doFilter(request, response)
void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException;
// 销毁
public void destroy();
}
public interface FilterChain {
void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException;
}
参考:
每天用心记录一点点。内容也许不重要,但习惯很重要!