Servlet 2.x 规范

Servlet 2.x 规范

sun 公司制订的一种基于 Java 技术的 WEB 服务器功能的组件规范。1997 年六月,Servlet 1.0 版本发行,最新版本 Servlet 4.0 处于研发状态。

所谓的 Servlet 容器,有时候也称作为 Servlet 引擎,作为 Web 服务器或应用服务器的一部分。通过请求和响应对话,提供 Web 客户端与 Servlets 交互的能力。容器管理 Servlets 实例以及它们的生命周期。

一、Servlet 组件

Servlet 容器的组件大致可以分为以下几类:

Servlet 组件
  ├── 服务组件
  |    ├── javax.servlet.Servlet
  |    └── javax.servlet.Filter(since Servlet 2.3)
  |
  ├── 上下文组件
  |    ├── javax.servlet.ServletContext
  |    ├── javax.servlet.http.HttpSession
  |    ├── javax.servlet.http.HttpServletRequest
  |    ├── javax.servlet.http.HttpServletResponse
  |    └── javax.servlet.http.Cookie(客户端)
  |
  ├── 配置
  |    ├── javax.servlet.ServletConfig
  |    └── javax.servlet.FilterConfig(since Servlet 2.3 )
  |
  ├── 输入输出
  |    ├── javax.servlet.ServletInputStream
  |    └── javax.servlet.ServletOutputStream
  |
  ├── 异常
  |    └── javax.servlet.ServletException
  |
  ├── 事件(since Servlet 2.3 )
  |    ├── 生命周期类型
  |    |      ├── javax.servlet.ServletContextEvent
  |    |      ├── javax.servlet.http.HttpSessionEvent
  |    |      └── java.servlet.ServletRequestEvent
  |    ├── 属性上下文类型
  |    |      ├── javax.servlet.ServletContextAttributeEvent
  |    |      ├── javax.servlet.http.HttpSessionBindingEvent
  |    |      └── javax.servlet.ServletRequestAttributeEvent
  |    |
  ├── 监听器(since Servlet 2.3)
  |    ├── 生命周期类型
  |    |      ├── javax.servlet.ServletContextListener
  |    |      ├── javax.servlet.http.HttpSessionListener
  |    |      ├── javax.servlet.http.HttpSessionActivationListener
  |    |      └── javax.servlet.ServletRequestListener
  |    |
  └────└── 属性上下文类型
              ├── javax.servlet.ServletContextAttributeListener
              ├── javax.servlet.http.HttpSessionAttributeListener
              ├── javax.servlet.http.HttpSessionBindingListener
              └── javax.servlet.ServletRequestAttributeListener

Servlet 2.x 组件关系

  1. Servlet 接口:init(ServletConfig config)、service(ServletRequest req, ServletResponse res)、destroy()
  2. GenericServlet 抽象类:实现了 Servlet 接口中的 init, destroy 方法
  3. HttpServlet 抽象类:继承了 GenericServlet 抽象类,实现了 service()
  4. ServletConfig 接口:String getInitParameter(String paraName)
  5. ServletRequest 接口:HttpServletRequest 的父接口
  6. ServletResponse 接口:HttpServletResponse 的父接口

一、Servlet

1.1 Servlet 的生命周期

Servlet 的生命周期指 Servlet 容器如何去创建 Servlet 对象、如何调用 Servlet 对象的方法来处理请求、以及如何销毁 Servlet 对象的整个过程。

Servlet 生命周期的三个阶段:

(1) 初始化

当容器启动或者第一次执行时,Servlet#init(ServletConfig) 方法被执行,初始化当前 Servlet 。

(2) 处理请求

当 HTTP 请求到达容器时,Servlet#service(ServletRequest, ServletResponse) 方法被执行,来处理请求。

(3) 销毁

当容器关闭时,容器将会调用 Servlet#destroy() 方法被执行,销毁当前 Servlet。

1.2 Servlet 如何处理请求资源路径

  1. Servlet 容器会先假设访问的是一个 Servlet ,会依据应用名(appname)找到应用所在的文件夹,然后找到 web.xml 文件。

  2. 匹配

    • 精确匹配(完全匹配)
    • 通配符匹配:使用 * 匹配任意长度的字符串。eg: /*
    • 后缀匹配:使用 . 开头,后面可以接任意字符。eg: .do
  3. 如果都不匹配,则容器认为访问的是一个静态资源文件(html/css/js),如果找到则返回,否则返回404。

1.3 Servlet 是如何运行的?

  1. 浏览器依据 ip, port 建立与 Servlet 容器之间的连接。
  2. 浏览器将请求数据打包(即按照 http 协议的要求,将相关数据封闭成一个数据包,即请求数据包)并发送给 Servlet 容器。
  3. Servlet 容器解析请求数据包,并将解析后的数据放到 request 对象上。同时创建一个 response 对象。
  4. Servlet 容器依据请求资源路径找到 Servlet 的配置,然后创建 Servlet 对象。
  5. Servlet 调用 service 方法,并且会将事先创建好的 request 对象和 response 对象作为 service 方法的参数传递给 Servlet 对象。
  6. Servlet 通过 request 对象获得请求参数,进行相应的处理,然后将处理结果写到 response 对象上。
  7. Servlet 读取 response 对象上的数据,然后将处理结果打包(响应数据包)并发送给浏览器。
  8. 浏览器解析响应数据包,将返回的数据展现给用户。

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 规范当中定义的一种特殊的组件,用来监听容器产生的事件并进行处理。

容器会产生两大类事件:

  1. 生命周期相关的事件:容器在创建或者销毁 request, servletContext(Servlet 上下文)时产生的事件。对应的接口有 ServletRequestListener、ServletContextListener。
  2. 绑定相关的事件:容器调用了 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;
}

Filter 生命周期如下:

(1) 初始化

当容器启动时,Filter#init(FilterConfig) 方法被执行,初始化当前 Filter。

(2) 处理请求

当 HTTP 请求到达容器时,Filter#doFilter(ServletRequest,ServletResponse,FilterChain) 方法被执行,来拦截请求,在 Servlet#service(ServletRequest,ServletResponse) 方法调用前执行。

(3) 销毁

当容器关闭时,容器将会调用 Filter#destroy() 方法被执行,销毁当前 Filter。

参考:

  1. 《Servlet 规范》:https://www.runoob.com/servlet/servlet-life-cycle.html

每天用心记录一点点。内容也许不重要,但习惯很重要!

posted on 2019-01-01 20:34  binarylei  阅读(364)  评论(0编辑  收藏  举报

导航