乐趣区

深入理解Servlet

1、什么是 Servlet ?

Servlet(Server Applet)是 Java Servlet 的简称,称为小服务程序或服务连接器,用 Java 编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态 Web 内容。

狭义的 Servlet 是指 Java 语言实现的一个接口,广义的 Servlet 是指任何实现了这个 Servlet 接口的类,一般情况下,可以将 Servlet 理解为后者。Servlet 运行于支持 Java 的应用服务器中。

从原理上讲,Servlet 可以响应任何类型的请求,但绝大多数情况下 Servlet 只用来扩展基于 HTTP 协议的 Web 服务器。(内容摘自百度百科

* 概念:运行在服务器端的小程序
    * Servlet 就是一个接口,定义了 Java 类被浏览器访问到 (tomcat 识别) 的规则。* 将来我们自定义一个类,实现 Servlet 接口,复写方法。

创建项目进行代码演示:

/**
 * Created by RookieLi on 2019/4/22.
 */
public class ServletDemo implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {}

    @Override
    public ServletConfig getServletConfig() {return null;}

    // 提供服务的方法
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse)
            throws ServletException, IOException {System.out.println("hello,servlet");
    }

    @Override
    public String getServletInfo() {return null;}

    @Override
    public void destroy() {}
}

在 web.xml 中配置:

<servlet>
    <servlet-name>demo1</servlet-name>
    <servlet-class>com.rookie.web.ServletDemo</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>demo1</servlet-name>
    <url-pattern>/demo</url-pattern>
</servlet-mapping>

当在浏览器中输入路径:http://localhost:8080/demo
控制台会输出:hello,servlet

执行的原理:

A、当服务器接受到客户端浏览器的请求后,会解析请求 URL 路径,获取访问的 Servlet 的资源路径。B、查找 web.xml 文件,是否有对应的 <url-pattern> 标签体内容。C、如果有,则在找到对应的 <servlet-class> 全类名

D、tomcat 会将字节码文件加载进内存,并且创建其对象

E、调用其 service 方法

Servlet 中的生命周期方法:

A、被创建:执行 init 方法,只执行一次
   Servlet 何时被创建?* 默认情况下,第一次被访问时,Servlet 被创建
        * 可以配置执行 Servlet 的创建时机。* 在 <servlet> 标签下配置
                a. 第一次被访问时,创建
                    * <load-on-startup> 的值为负数
                b. 在服务器启动时,创建
                    * <load-on-startup> 的值为 0 或正整数
        * Servlet 的 init 方法,只执行一次,说明一个 Servlet 在内存中只存在一个对象,Servlet 是单例的。* 多个用户同时访问时,可能存在线程安全问题。* 解决:尽量不要在 Servlet 中定义成员变量。即使定义了成员变量,也不要对修改值。B、提供服务:执行 service 方法,执行多次
        * 每次访问 Servlet 时,Service 方法都会被调用一次。C、被销毁:执行 destroy 方法,只执行一次
        * Servlet 被销毁时执行。服务器关闭时,Servlet 被销毁。* 只有服务器正常关闭时,才会执行 destroy 方法。* destroy 方法在 Servlet 被销毁之前执行,一般用于释放资源。

Servlet 3.0 (重点)

优点:支持注解配置。可以不需要 web.xml 了。

代码演示

@WebServlet("/demo666")
public class ServletDemo2 implements Servlet {
    
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {}

    @Override
    public ServletConfig getServletConfig() {return null;}

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse)
            throws ServletException, IOException {System.out.println("servlet 3.0 给力 666");
    }

    @Override
    public String getServletInfo() {return null;}

    @Override
    public void destroy() {}
}

当在浏览器中输入路径:http://localhost:8080/demo666
控制台会输出:servlet 3.0 给力 666

@WebServlet 源码剖析

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebServlet {String name() default "";    // 相当于 <Servlet-name>

    String[] value() default {};    // 代表 urlPatterns()属性配置

    String[] urlPatterns() default {};    // 相当于 <url-pattern>

    int loadOnStartup() default -1;    // 相当于 <load-on-startup>

    WebInitParam[] initParams() default {};

    boolean asyncSupported() default false;

    String smallIcon() default "";

    String largeIcon() default "";

    String description() default "";

    String displayName() default "";}

Servlet 的体系结构

    Servlet -- 接口
        |
    GenericServlet -- 抽象类
        |
    HttpServlet  -- 抽象类
    
A、GenericServlet:将 Servlet 接口中其他的方法做了默认空实现,只将 service() 方法作为抽象
    * 将来定义 Servlet 类时,可以继承 GenericServlet,实现 service() 方法即可

B、HttpServlet:对 http 协议的一种封装,简化操作
    * 定义类继承 HttpServlet
    * 复写 doGet/doPost 方法    
    
C、Servlet 相关配置
    * urlpartten:Servlet 访问路径
        * 一个 Servlet 可以定义多个访问路径:@WebServlet({"/demo6","/demo66","/demo666"})
            在浏览器中输入不同的请求路径,都可以访问到资源。http://localhost:8080/demo6
            http://localhost:8080/demo66
            http://localhost:8080/demo666
        B、路径定义规则:1. /xxx:路径匹配
            2. /xxx/xxx: 多层路径,目录结构
            3. *.do:扩展名匹配    

退出移动版