Servlet

一、Servlet 概述

Servlet 就是一个运行在 web 服务器上的一个小的 java 程序(也是一个接口),用于处理从 web 客户端发送的请求并对请求做出响应

1.1 使用 Servlet

  • 编写一个 Java 类实现 Servlet 接口
  • 配置 Servlet

1.2 具体使用步骤(实际开发不会用该方法)

步骤:

  1. 创建包和类
    image-20211114163825952

  2. 实现 Servlet 接口

    package com.servlet.demo1;
    
    import java.io.IOException;
    
    import javax.servlet.Servlet;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    public class HelloServlet implements Servlet{
    	@Override
        public void destroy() {
            System.out.println("destroy");
        }
    
        @Override
        public ServletConfig getServletConfig() {
            return null;
        }
    
        @Override
        public String getServletInfo() {
            return null;
        }
    
        //该init函数用于初始化该servlet,该函数只会被调用一次(当用户第一次访问该servlet时被调用)
        @Override
        public void init(ServletConfig arg0) throws ServletException {
            System.out.println("init it");
        }
    
    	@Override
    	//	用来处理客户的请求,并且对请求做出响应的方法
    	public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
    		// 向页面输出字符串
    		resp.getWriter().println("hello servlet");
    	}
    }
    
  3. WEB-INF 中的 web.xml 配置上面的 java 类,即需要配置servlet

    切换到 source 编辑 web.xml:
    image-20211114170957462
    image-20211114171316401

    web.xml 中配置 servlet:
    image-20211114171703137
    注意:servlet-mapping 中的 servlet-name 和 servlet 中的 servlet-name 必须一致

  4. 访问 servlet

    通过 http://localhost:8081/hello 就可以访问,因为在 web.xml 中配置的访问路径是/hello

    访问成功的界面:

    image-20211114172244323

1.3 Servlet 执行流程

image-20211114173333067

执行流程:

  1. 在web.xml 中找到与浏览器中的地址相匹配的配置的访问路径
  2. 通过该访问路径找到与之映射的 servlet 的名称
  3. 该 servlet 名称对应 servlet 标签的 servlet 名称
  4. 在 servlet 标签中找到配置的 servlet类 的全路径(servlet-class)
  5. 这样就找到了我们写的 servlet类,执行该类中的 service() 方法

 

二、Servlet 的实现关系

2.1 基本实现关系

Servlet 接口

​ |-------GenericServlet 类 (通用Servlet,与协议无关)

​ |---------HttpServlet 类 (Http 专用的Servlet)

 

2.2 实现关系概述

       HttpServlet 类是专门用来处理 Http 请求的。通常编写一个 Servlet 一般都会让这个 Servlet 继承 HttpServlet重写 service 方法

       在 service 方法中根据请求方法的不同执行不同的 doXXX 方法(get 方法执行 doGet 方法,post方法执行 doPost 方法),往往要请求的除了里的内容是一致的,所以需要让 doGet 和 doPost 相互调用来简化编程。

       

2.3 Eclipse 中使用 Servlet 模板

image-20211115095813001 image-20211115100321007 image-20211115100456436 image-20211115100549647 image-20211115100549647

注意:在 Eclipse 使用 Servlet 模板这种方法,甚至不需要在web.xml 中去配置 servlet,模板已经配置好了

 

三、servlet的生命周期

3.1 servlet 生命周期相关的方法

与 servlet 生命周期相关的方法有:init、service、destroy

  • Servlet 是在第一次被访问时会被实例化,只要 Servlet 一被实例化那 Servlet 中的init 方法就会被执行**(init 只会执行一次)**
  • 任何一次从客户端发送过来的请求,那 Servlet中的 service 方法就会被执行(在service 方法内部根据请求的发送不同调用不同的 doXXX 方法)
  • 当 Servlet 从服务器中移除或服务器关闭的时候 Servlet 对象被销毁,里面的 destroy 方法就会被执行,然后垃圾回收就会将其回收掉

 

3.2 servlet 的启动时加载

Servlet 对象是在第一次被访问时会被创建,init方法执行。假设在init 方法中做了一些比较耗时的操作(如:加载了一些配置文件并且解析可能花费3s)。第一个用户第一次访问这个servlet时就需要等待3s。如何使第一个用户在第一次访问时不需要花费这么长和时间?

3.2.1 servlet 启动时加载概念

       servlet 默认在第一次访问的时候创建的对象,现在通过配置将 servlet 的实例化的过程放在服务器启动时(让服务器启动时创建 servlet 对象)。此时之前花费掉的时间就会在服务器启动时一起花费掉了**(同步进行)**。对于用户来说就不需要花费额外的时间了

 

3.2.2 配置启动时加载

在web.xml 中 servlet节点下添加 load-on-startup 节点

image-20211118095304711

      注意:需要给 load-on-startup 节点 传一个整数,代表 servlet 的优先级。数值越小,优先级越高。一般从2开始,因为 tomcat 的默认有个 servlet,其配置的优先级为 1
image-20211118095552450
       会发现,在服务器启动时 servlet 就创建了实例,不用等到在浏览器中输入地址访问 servlet 时再创建实例,节约了时间

 

3.3 Servlet 的访问路径的配置

3.3.1 servlet 中 url-pattern的配置

配置方式:

  • 完全路径匹配

    以 / 开始 如:/aaa/ServletDemo
    image-20211118100435096
    浏览器中输入:localhost:8081/web_test/ServletDemo2 才能匹配

  • 目录匹配

    以 / 开始,以 * 结束(*表示匹配任意内容) 如:/aaa/*
    image-20211118100800653 浏览器中输入:localhost:8081/web_test/aaa/adbjojsbfhf(任意内容) 匹配

  • 扩展名匹配

    不能以 / 开始,以 * 开始. 紧跟其后,代表以什么什么结尾 如:*.do
    image-20211118101057828

    浏览器中输入:localhost:8081/web_test/servlet.abc 匹配
     

3.3.2 访问的优先级

完全路径匹配 > 目录匹配 > 扩展名匹配

 

四、servlet 中的对象

4.1 ServletConfig 对象

ServletConfig 用来获得 Servlet 的相关配置对象

4.1.1 获得ServletConfig 对象

方法:getServletConfig()
image-20211118101737752

  • 获取servlet 初始化参数
  • 获得 ServletContext 对象
  • 获得 Servlet 名称

演示:

  • 配置初始化参数
    image-20211118102350027
  • 获取参数
    image-20211118104624992
  • 查看结果
    image-20211118104454803

4.2 ServletContext 对象

4.2.1 ServletContext 概念

ServletContext:Servlet 上下文对象。ServletContext 对象知道 Servlet 之前和之后的内容。一个 web 项目只有一个该对象。在服务器启动时为每个 web 项目创建一个单独的ServletContext 对象

 

4.2.2 ServletContext 对象作用

  • 用来获取 web 项目信息
    • 获取文件的 MIME 类型:getMimeType()
    • 获取 web 项目请求工程名:getContextPath()
    • 获取 web 项目全局初始化参数:getInitParameter()、getInitParameterNames()

全局初始化参数配置如下:
image-20211118105823461

  • 读取 web 项目下的文件

    之前是使用IO流就可以读取文件(java项目中)。现在是一个web项目,web项目需要发布到tomcat 下才能访问。获取 web 项目下的文件若使用传统的IO就会出现问题(原因:路径中使用的是相对路径,相对的是JRE环境)

image-20211118140048554
image-20211118140402822

  • 作为域对象存取数据

    域对象:指有一定作用范围的对象。当数据存入到域对象中,这个数据就会有一定的作用范围

1. ServletContext 作为域对象的 API:
  1. 存入数据:setAttribute()
  2. 获取数据:getAttribute()
  3. 移除数据:removeAtrribute()
2. ServletContext 作为域对象的作用范围

      ServletContext 在服务器启动时为每个 web 项目单独创建一个 ServletContext 对象。当web 项目从服务器中移除或是关闭服务器的时候 ServlContext 对象会被销毁。向 ServletContext 中保存的数据会一致存在(当服务器关闭的时候 ServletContext 对象被销毁,此时里面的数据才失效

 

4.3 Response 对象

4.3.1 Response 对象的 API

1. 关于响应行
  • 设置响应的状态码:getStatus()
2. 关于响应头

针对一个key 对一个value的, set 开头:

  • setDateHeader()
  • setHeader()
  • setIntHeader()

针对一个key 对多个value的, add 开头:

  • addDateHeader()
  • addHeader()
  • addIntHeader()
3. 关于响应体(向页面输出的内容)
  • getOutputStream()
  • getWriter()
4. 其他的API
  • 重定向:sendRedirect()

  • 设置浏览器打开页面时采用的字符集:setContentType()

  • 设置响应字符流的缓冲区的字符集:setCharsetEncoding()

 

4.3.2 Response 对象 API 的演示

1. 设置状态码和完成重定向

      单独设置状态码是没有意义的,必须要使用重定向(状态码302和Location结合使用的效果

// ResponseDemo2.java
/**
 * 设置响应状态码
 */
public class ResponseDemo1 extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 设置响应的状态码
		// response.setStatus(404);
		// 完成重定向
		response.setStatus(302);
		// 设置响应头
		response.setHeader("Location", "/web_test/ResponseDemo2");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		// TODO Auto-generated method stub
		doGet(request, response);
	}
}

方法二:直接使用 sendRedirect()

 

2. 定时刷新
public class ResponseDemo1 extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 定时刷新
		response.setContentType("text/html;charset=UTF-8");
		response.getWriter().println("5秒以后跳转");
		response.setHeader("Refresh", "5;url=/web_test/ResponseDemo2");
	}
}

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐