Javaweb(02) servlet

一、技术体系的流程图

在这里插入图片描述

二、Servlet(java 服务器小程序)概念

servlet是Server Applet的简称,翻译过来就是服务程序.好吧,这么说你可能还是不太懂,简单的讲,这个servlet是运行在服务器上的一个小程序,用来处理服务器请求的.进一步讲,我们知道,一般的网页程序,是由我们通过浏览器访问来实现的,在这个过程中,我们的浏览器发送访问请求,服务器接收请求,并对浏览器的请求作出相应的处理.这就是我们熟悉的B/S模型(浏览器-服务器模型).而servlet就是对请求作出处理的组件,运行于支持Java的应用服务器中

总结特点:

  1. 他是由服务器端调用和执行的(一句话:是Tomcat解析和执行)
  2. 他是用java语言编写的, 本质就是Java类
  3. 他是按照Servlet规范开发的(除了tomcat->Servlet weblogic->Servlet)
  4. 功能强大,可以完成几乎所有的网站功能(在以前,我们老程员,使用Servlet开发网站) 技术栈要求高

三、Servlet 基本使用

3.1 Servlet 开发方式说明

  1. servlet3.0 前使用 web.xml , servlet3.0 版本以后(包括 3.0)支持注解, 同时支持 web.xml配置
  2. ssm , springboot 后面全部使用注解,原生的Servlet 在项目中使用很少
  3. 不管使用哪种方式,本质都一样

3.2手动开发 Servlet

  1. 导入servlet-api.jar jar包(jar包在安装tomcat目录lib目录下)直接复制到idea目录下,一般在WEB-INF下建一个lib目录,放这里面
  2. 直接添加
  3. 在src 下 包 com.hspedu.servlet.HelloServlet.java ,并实现Servlet接口
package com.mzq.servlet_;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * @author MengZhiQiang
 * @version 1.0
 * @date 2022/3/30 18:27
 * 1. 开发一个Servlet 需要 实现Servlet接口
 * 2. 实现Servlet接口的方法5个
 */
public class HelloServlet implements Servlet {
   private int count = 0; //属性
   /**
    * 1.初始化 servlet
    * 2.当创建HelloServlet 实例时,会调用init方法
    * 3. 该方法只会被调用一次
    * @param servletConfig
    * @throws ServletException
    */
   @Override
   public void init(ServletConfig servletConfig) throws ServletException {
      System.out.println("init() 被调用");
   }

   /**
    * 返回ServletConfig 也就是返回Servlet的配置
    * @return
    */
   @Override
   public ServletConfig getServletConfig() {
      return null;
   }

   /**
    * 1. service方法处理浏览器的请求(包括get/post)
    * 2. 当浏览器每次请求Servlet时,就会调用一次service
    * 3. 当tomcat调用该方法时,会把http请求的数据封装成实现ServletRequest接口的request对象
    * 4. 通过servletRequest 对象,可以得到用户提交的数据
    * 5. servletResponse 对象可以用于返回数据给tomcat->浏览器
    * @param servletRequest
    * @param servletResponse
    * @throws ServletException
    * @throws IOException
    */
   @Override
   public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
      count++;
      //如果count的值,在不停的累计,说明HelloServlet是单例的
      System.out.println("hi HelloServlet~ count= " + count);
      //Tomcat每处理一次http请求,就生成一个新的线程
      System.out.println("当前线程id= " + Thread.currentThread().getId());

      //思考->从servletRequest对象来获取请求方式->
      //1. ServletRequest 没有得到提交方式的方法
      //2. ServletRequest 看看ServletRequest子接口有没有相关方法
      //3. 小技巧:ctrl+alt+b => 可以看到接口的子接口和实现子类
      //4. 把servletReqeust转成 HttpServletRequest引用
      //5. 仍然是Java基础的OOP
      HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
      String method = httpServletRequest.getMethod();
      if("GET".equals(method)) {
         doGet(); //用doGet() 处理GET请求
      } else if("POST".equals(method)) {
         doPost(); //用doPost() 处理POST请求
      }

   }
   /**
    * 用于响应get请求的
    */
   public void doGet() {
      System.out.println("doGet() 被调用..");
   }

   /**
    * 用于响应post请求的
    */
   public void doPost() {
      System.out.println("doPost() 被调用..");
   }
   /**
    * 返回servlet信息,使用较少
    * @return
    */
   @Override
   public String getServletInfo() {
      return null;
   }

   /**
    * 1. 该方法是在servlet销毁时,被调用
    * 2. 只会调用一次
    */
   @Override
   public void destroy() {

   }
}

  1. 在 web.xml 中去配置 servlet 程序的访问地址
<!--1. servlet-name: 给Servlet取名(程序员决定), 该名字唯一-->
    <!--2. servlet-class: Servlet的类的全路径: Tomcat在反射生成该Servlet需要使用-->
    <!--3. url-pattern: 这个就是该servlet访问的url的配置(路径)-->
    <!--4. 这时我们应该这样访问servlet http://localhost:8080/servlet/helloServlet-->
    <!--5. url-pattern 取名是程序员决定的-->
    <!--6. load-on-startup 表示在tomcat 启动时,会自动的加载servlet实例-->
    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.mzq.servlet_.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/helloServlet</url-pattern>
    </servlet-mapping>
  1. 浏览器访问localhost:8080/helloServlet

四、浏览器调用 Servlet 流程分析

在这里插入图片描述

在这里插入图片描述

五、Servlet 生命周期

5.1 主要有三个方法

  1. init()初始化阶段
  2. service()处理浏览器请求阶段
  3. destroy()终止阶段

在这里插入图片描述

  • 初始化阶段

    Servlet容器会加载Servlet,加载完成后,Servlet 容器会创建一个 Servlet 实例并调用 init()方法,init()方法只会调用一次,,

  • 处理浏览器请求阶段(service 方法)

每收到一个 http 请求,服务器就会产生一个新的线程去处理[线程]即:service方法,是进行数据处理的,只要接受了一次请求,就会被调用一次

  • 终止阶段 destory 方法(体现 Servlet 完整的生命周期)

    当 web 应用被终止,或者 Servlet 容器终止运行,或者 Servlet 类重新装载时,会调用 destroy()方法比如重启 tomcat ,或者 redeploy web 应用

一般来讲,servlet只会初始化一次,也就是整个过程中只存在一个servlet对象,即便是有多次访问,依然只有一个对象,这个对象是可以复用的.所谓的生命周期就是浏览器访问时,会先到xml文件找到映射路径,查看是否存在Servlet实例,不存在 Servlet 实例时创建实例并调用 init()方法,调用service方法处理浏览器请求,第二次请求时直接调用service方法,服务器关闭,调用 destory 方法,web 应用被终止.

六、通过继承 HttpServlet 开发 Servlet

在实际项目中,都是使用继承 HttpServlet 类开发 Servlet 程序,更加方便

继承图:

在这里插入图片描述

  1. 编写一个类去继承 HttpServlet 类

  2. 根据业务需要重写 doGet 或 doPost 方法

    public class HiServlet extends HttpServlet {
    
        //重写HttpServlet的doGet 和 doPost
        //alt +insert
    
        /**
         * 处理doGet请求
         * @param req
         * @param resp
         * @throws ServletException
         * @throws IOException
         */
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("HiServlet doGet()...");
        }
    
        /**
         * 处理doPost
         * @param req
         * @param resp
         * @throws ServletException
         * @throws IOException
         */
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("HiServlet doPost()...");
        }
    }
    
  3. 到 web.xml 中的配置 Servlet 程序

     <servlet>
            <servlet-name>HiServlet</servlet-name>
            <servlet-class>com.mzq.servlet_.HiServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>HiServlet/servlet-name>
            <url-pattern>/hiServlet</url-pattern>
        </servlet-mapping>
    
  4. 测试

七、IDEA 开发 Servlet 程序

  1. 直接创建

    在这里插入图片描述

在这里插入图片描述

其余过程和上面 通过继承 HttpServlet 开发 Servlet一样

八、Servlet 注意事项和细节

  1. Servlet 是一个供其他 Java 程序(Servlet 引擎)调用的 Java 类,不能独立运行

  2. 针对浏览器的多次 Servlet 请求,通常情况下,服务器只会创建一个 Servlet 实例对象,也就是说 Servlet 实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至web 容器退出/或者 redeploy 该 web 应用,servlet 实例对象才会销毁 【示意图】

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8L72xKX8-1648651400735)(\img\08.png)]

  3. 在 Servlet 的整个生命周期内,init 方法只被调用一次。而对每次请求都导致 Servlet 引擎调用一次 servlet 的 service 方法。

  4. 对于每次访问请求,Servlet 引擎都会创建一个新的 HttpServletRequest 请求对象和一个新的 HttpServletResponse 响应对象,然后将这两个对象作为参数传递给它调用的 Servlet的 service()方法,service 方法再根据请求方式分别调用 doXXX 方法

  5. 如果在<servlet>元素中配置了一个<load-on-startup>元素,那么 WEB 应用程序在启动时,就会装载并创建 Servlet 的实例对象、以及调用 Servlet 实例对象的 init()方法, 例如(定时发送邮件的服务/自动启动->完成任务)

九、 Servlet - 注解方式

  1. 编写类OkServlet去继承HttpServlet
  2. 注解方式配置OkServlet, 一个Servlet支持配置多个urlPattern
/**
 * 解读
 * 1. @WebServlet 是一个注解 => java基础->注解
 * 2. @WebServlet 源码
 * @Target({ElementType.TYPE})
 * @Retention(RetentionPolicy.RUNTIME)
 * @Documented => 在javadoc工具生成文档有记录
 * public @interface WebServlet {
 *     String name() default "";
 *
 *     String[] value() default {};
 *
 *     String[] urlPatterns() default {};
 *
 *     int loadOnStartup() default -1;
 *
 *     WebInitParam[] initParams() default {};
 *
 *     boolean asyncSupported() default false;
 *
 *     String smallIcon() default "";
 *  }
 *  3. urlPatterns 对应 web.xml 的 <url-pattern></url-pattern>
 *  4. {"/ok1", "/ok2"} 可以给OkServlet配置多个 url-pattern
 *  5. 相当于这个@WebServlet(urlPatterns = {"/ok1", "/ok2"}) 代替了 web.xml的配置
 *     底层使用了 反射+注解+IO+集合 来完成一个支撑
 *  6. 浏览器可以这样访问OkServlet时,可以 http://localhost:8080/servlet/ok1 或者
 *     http://localhost:8080/servlet/ok2
 *  7. 同学们有很多小问号? 解密. => 一会老师再说.
 *  8. 我们可以根据 @interface WebServlet 源码知道可以配置哪些
 *  web.xml init-param 在注解中,如何指定呢? 老师看了源码,老师搞定
 *          <init-param>
 *             <param-name></param-name>
 *             <param-value></param-value>
 *         </init-param>
 *  9. 注解方式开发Servlet和 web.xml配置servlet 流程机制是一样
 *  10. /ok1/aa /ok1/bb /ok1/cc /ok1/aa/bb/cc /ok2
 *  11. *.action 这时 zs.action ls.action
 *  12. http://localhost:8080/servlet/register.html
 */
@WebServlet(urlPatterns = {"/ok1/aa"})
public class OkServlet extends HttpServlet {

    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("注解方式 OkServlet init()被调用");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("注解方式 OkServlet doPost()");

    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("注解方式 OkServlet doGet()");
        System.out.println(req.getRemoteAddr());
    }

}

9.1Servlet urlPattern 配置

  • 精确匹配:

    • 配置路径 : @WebServlet(“/ok/zs”)
    • 访问 servlet: localhost:8080/servlet/ok/zs
  • 目录匹配:

    • 配置路径 : @WebServlet(“/ok/*”)
    • 访问文件: localhost:8080/servlet/ok/aaa或localhost:8080/servlet/ok/bbb
  • 扩展名匹配:

    • 配置路径 : @WebServlet(“*.action”)
    • 访问文件: localhost:8080/hsp/zs.action或localhost:8080/hsp/ls.action
  • 任意匹配:

    • 配置路径 : @WebServlet(“/”) @WebServlet(“/*”)
    • 访问文件: localhost:8080/hsp/aaa localhost:8080/hsp/bbb localhost:8080/hsp/ccc

9.2注意事项和使用细节

  1. 当 Servlet 配置了 “/”, 会覆盖 tomcat 的 DefaultServlet, 当其他的 utl-pattern 都匹配不 上 时 , 都 会 走 这 个 Servlet,这 样 可 以 拦 截 到 其 它 静 态 资 源
  2. 当 Servelt 配置了 “/*”, 表示可以匹配任意访问路径
  3. 建议不要使用 / 和 /*, 建议尽量使用精确匹配
  4. 优先级遵守: 精确路径 > 目录路径 > 扩展名路径 > /* > /

bb localhost:8080/hsp/ccc

9.2注意事项和使用细节

  1. 当 Servlet 配置了 “/”, 会覆盖 tomcat 的 DefaultServlet, 当其他的 utl-pattern 都匹配不 上 时 , 都 会 走 这 个 Servlet,这 样 可 以 拦 截 到 其 它 静 态 资 源
  2. 当 Servelt 配置了 “/*”, 表示可以匹配任意访问路径
  3. 建议不要使用 / 和 /*, 建议尽量使用精确匹配
  4. 优先级遵守: 精确路径 > 目录路径 > 扩展名路径 > /* > /
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值