Servlet及相关接口 【最全总结】

1、Servlet 简介

1)从广义上来讲,Servlet 规范是 Sun 公司制定的一套技术标准,包含与 Web 应用相关的一系列接口,是 Web 应用实现方式的宏观解决方案。而具体的 Servlet 容器负责提供标准的实现。

2)从狭义上来讲,Servlet 指的是 javax.servlet.Servlet 接口及其子接口,也可以指实现了Servlet 接口的实现类。

3)Servlet 作为服务器端的一个组件,它的本意是“服务器端的小程序”。Servlet 的实例对象由 Servlet 容器负责创建;Servlet 的方法由容器在特定情况下调用;Servlet 容器会在 Web 应用卸载时销毁 Servlet 对象的实例。

2、第一个 Servlet

2.1 编写 Servlet

1) 创建自己的类 HelloServlet,实现 Servlet 接口,并编写 service 方法

public class HelloServlet implements Servlet{

	@Override
	public void init(ServletConfig config) throws ServletException {
	}
	
	@Override
	public ServletConfig getServletConfig() {
		return null;
	}
	
	@Override
	public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
		System.out.println("我是不是被执行了?");
	}
	
	@Override
	public String getServletInfo() {
		return null;
	}
	
	@Override
	public void destroy() {
	}
}

2) 在 web.xml 中配置 servlet 信息

<servlet>
	<servlet-name>helloServlet</servlet-name>
	<servlet-class>com.atguigu.listener.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>helloServlet</servlet-name>
	<url-pattern>/helloworld</url-pattern>
</servlet-mapping>

配置详解:
<servlet></servlet>:这个之间配置的是Servlet的类信息
<servlet-name>:这是 Servlet 的别名,一个名字对应一个 Servlet。相当于变量名
<servlet-class>:Servlet 的全类名,服务器会根据全类名找到这个 Servlet
<servlet-mapping></servlet-mapping>:这个之间配置的是 Servlet 的请求映射信息
<servlet-name>:Servlet的别名,说明这个Servlet将会响应下面url-pattern的请求
<url-pattern>:Servlet响应的请求路径。如果访问这个路径,这个Servlet就会响应。这个url-pattern可以配置多个,这时表示的就是访问这些url都会触发这个Servlet进行响应

3) 运行浏览器,访问刚才配置的 url 路径,Servlet 的 service 方法就会被调用。

2.2 运行原理

在这里插入图片描述

3、Servlet 技术体系

3.1 Servlet 的层次关系

在这里插入图片描述

3.2 Servlet 接口

在这里插入图片描述

1)Servlet 接口是 Servlet 的规范。
2)init(ServletConfig config):Servlet 初始化函数。初始化时 ServletConfig 会被传入
3)ServletConfig getServletConfig():获取 ServletConfig 对象
4)service(ServletRequest req, ServletResponse res):收到请求后的执行方法
5)String getServletInfo():返回此 Servlet 的描述信息
6)void destroy():Servlet 的销毁方法

3.3 GenericServlet 抽象类

在这里插入图片描述

1) Servlet,ServletConfig 的实现类。里面可以实现 Servlet 的功能,可以获取 ServletConfig 的信息
2)String getInitParameter(String name):获取 Servlet 初始化参数值,初始化参数在 web.xml 的 Servlet 中 配 置 ,
<init-param>
<param-name>user</param-name>
<param-value>abc</param-value>
<init-param/>
3)Enumeration<String> getInitParameterNames():获取 Servlet 初始化的所有参数 name 值
4)ServletConfig getServletConfig():获取 ServletConfig 对象
5)ServletContext getServletContext():获取 ServletContext 对象
6)String getServletInfo():获取 Servlet 的描述信息
7)void init(ServletConfig config):从 Servlet 实现的 init 方法,这里面调用了自己的 init方法。
8)void init():自己的 init 方法
9)abstract void service:抽象方法,继承此类的子类必须自己实现此方法。每次请求都会调用此方法。
10)String getServletName():获取 Servlet 的名字

3.4 HttpServlet 抽象类

在这里插入图片描述

1)HttpServlet 继承了 GenericServlet,并实现了 service 方法。在 service 方法中,将 ServletRequest 和 ServletResponse 转换为了 HttpServletRequest 和 HttpServletResponse,用来专门处理我们的 Http 请求。

2)Servlet(ServletRequest, ServletResponse) 方法在完成对请求和响应的强转之后调用了方法,在被调用的方法中对请求类型进行了判断,各种请求调用自己相应的 doXXX 方法。而我们常用的就是 doGet() 和 doPost() 方法。

3)在我们以后的使用中,都使用继承 HttpServlet 的方式,重写 doGet 和 doPost 方法即可。
在浏览器发送请求的时候,如果是 get 请求,将会调用 doGet()方法,如果是 post 请求,将会调用 doPost()方法。

4)继承 HttpServlet 的新的 Servlet 写法如下(web.xml 配置与之前相同)

public class FirstServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
		public FirstServlet() {
		super();
	}
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("doGet()......");
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("doPost()......");
	}
}

4、Servlet 生命周期

4.1 什么是生命周期

应用程序中的对象不仅在空间上有层次结构的关系,在时间上也会因为处于程序运行过程中的不同阶段而表现出不同状态和不同行为 — — 这就是对象的生命周期。
简单的叙述生命周期,就是对象在容器中从开始创建到销毁的过程。

4.2 Servlet 容器

Servlet 对象是 Servlet 容器创建的,生命周期方法都是由容器调用的。这一点和我们之前所编写的代码有很大不同。在今后的学习中我们会看到,越来越多的对象交给容器或框架来创建,越来越多的方法由容器或框架来调用,开发人员要尽可能多的将精力放在业务逻辑的实现上。

4.3 Servlet 生命周期

我们在编写 Servlet 的 HelloWorld 的时候,我们发现服务器在启动后,访问配置的 url 的时候好像调用了 Servlet 的几个方法。到底 Servlet 在容器中是如何创建,使用,消亡的。主要步骤:

4.3.1 Servlet 对象的创建

默认情况下,Servlet 容器第一次收到 HTTP 请求时创建对应 Servlet 对象。容器之所以能做到这一点是由于我们在注册 Servlet 时提供了全类名,容器使用反射技术创建了Servlet的对象。

4.3.2 Servlet 对象初始化

1)Servlet 容器创建 Servlet 对象之后,会调用 init(ServletConfig config) 方法,对其进行初始化。在 javax.servlet.Servlet 接口中,public void init(ServletConfig config) 方法要求容器将 ServletConfig 的实例对象传入,这也是我们获取 ServletConfig 的实例对象的根本方法。

2)为了简化开发,GenericServlet 抽象类中实现了 init(ServletConfig config)方法,将 init(ServletConfig config)方法获取到的 ServletConfig 对象赋值给了成员变量 ServletConfig config,目的是使其它方法可以共享这个对象。这时有一个问题:如果子类重写了这个init(ServletConfig config)方法,有可能会导致成员变量 config 对象赋值失败。所以 GenericServlet抽象类另外提供了一个无参的public void init()方法,并在init(ServletConfig config)方法中调用,作为子类进行初始化操作时重写使用。而这个无参的 init()方法之所以没有设计成抽象方法,是为了避免子类继承时强制实现这个方法带来的麻烦,使用者可以根据需要选择是否要覆盖这个方法。

4.3.3 处理请求

1)在 javax.servlet.Servlet 接口中,定义了 service(ServletRequest req, ServletResponse res) 方法处理 HTTP 请求,同时要求容器将ServletRequest 对象和 ServletResponse 对象传入。

2)在 HttpServlet 抽象类中,service(ServletRequest req, ServletResponse res)方法将 ServletRequest 对象和 ServletResponse 对象强 转为了 HttpServletRequest 、HttpServletResponse子类对象,这样更适合于HTTP请求的处理,所以在 doGet() 和 doPost() 方法中使用的就是 HttpServletRequest、HttpServletResponse 的实现类对象了。

4.3.4 Servlet 对象销毁

Web 应用卸载或服务器停止执行时会销毁 Servlet 对象,而销毁之前为了执行一些诸如释放缓存、关闭连接、保存数据等操作,所以设计了 public void destroy()方法。

步骤总结

1)Servlet 对象创建:接收到浏览器请求后,才创建对象

2)Servlet 初始化
创建对象之后,会调用 init()方法
作用:是在 Servlet 对象创建后,执行一些初始化操作
例如,读取一些资源文件,或建立某种连接
init()方法只在创建对象时执行一次,以后再接到请求时,就不执行了

3)Servlet 处理客户端请求
接收到请求之后调用 service()方法
在每次接到请求后都会执行

4)Servlet 面临对象的销毁
当前 Web 应用卸载之前调用 destroy()方法
在应用卸载之前,可能需要释放一些资源,关闭某些连接

5、ServletConfig 接口

在这里插入图片描述

5.1 ServletConfig 接口简介

封装了 Servlet 配置信息,这一点从接口的名称上就能够看出来。但同时,代表当前 Web 应用的 ServletContext 对象也封装到了 ServletConfig 对象中,使 ServletConfig 对象成为了获取ServletContext 对象的一座桥梁。

5.2 ServletConfig 对象的主要功能

1)获取 Servlet 名称
2)获取 Servlet 初始化参数
3)获取 ServletContext 对象

5.3 Servlet 初始化参数

在 Servlet 注册信息中,指定的一个参数,有参数名和参数值。在 servlet 标签内加入如下配置信息

<!-- Servlet初始化参数 -->
<init-param>
	<!-- 初始化参数的参数名 -->
	<param-name>Status</param-name>
	<!-- 初始化参数的值 -->
	<param-value>open</param-value>
</init-param>

对 Servlet 运行时如果想设置一些开关选项,就可以以配置文件的形式进行设置,在改变选项状态时,不需要修改源代码、重新编译,只需修改配置文件即可。

//获取初始化参数
String paramValue = servletConfig.getInitParameter("Status");

5.4 获取 ServletConfig 对象

1)在 GenericServlet 中,由容器传入 init(ServletConfig config)方法。

2)在GenericServlet中提供了public ServletConfig getServletConfig()方法用来获取ServletConfig对象。

3)如果继承了 HttpServlet,则可以直接调用 getServletConfig()方法获取 ServletConfig 对象

6、ServletContext 接口

在这里插入图片描述

1) web 容器在启动时,他会为每个 web 应用都创建一个对应的 ServletContext 对象。注意:一个web应用对应的是一个ServletContext对象。就行每个web应用就像是不同的餐厅,而 Servlet 是餐厅服务员,可以有很多,ServletContext 是这个餐厅的经理只能有一个。

2) 由于一个 web 应用程序的所有 Servlet 都共享的是同一个 ServletContext 对象,所以 ServletContext 对象也被称为 application 对象(web 应用程序对象)

3) 在应用程序中能够获取运行环境或者容器信息的对象通常称之为“上下文对象”。

4) ServletContext 的主要功能

  • 获取虚拟路径所映射的本地路径
    虚拟路径:浏览器访问 web 应用中资源时所使用的路径
    本地路径:资源在文件系统中的实际保存路径
  • application 域范围的属性
  • 获取 web 应用程序的初始化参数
    设置 Web 应用初始化参数的方式是在 web.xml 的根标签下加入如下代码
<!-- Web应用初始化参数 -->
<context-param>
	<param-name>ParamName</param-name>
	<param-value>ParamValue</param-value>
</context-param>

获取 Web 应用初始化参数

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {
	//1.获取ServletContext对象
	ServletContext context = this.getServletContext();
	//2.获取Web应用初始化参数
	String paramValue = context.getInitParameter("ParamName");
	System.out.println("paramValue="+paramValue);
}

7、HttpServletRequest 接口

该接口是 ServletRequest 接口的子接口,封装了 HTTP 请求的相关信息,由 Servlet 容器创建其实现类对象并传入 service(ServletRequest req, ServletResponse res)方法中。我们请求的详细信息都可以通过 HttpServletRequest 接口的实现类对象获取。这个实现类对象一般都是容器创建的,我们不需要管理。
HttpServletRequest 主要功能:

7.1 获取请求参数

1)什么是请求参数?
请求参数就是浏览器向服务器提交的数据

2)浏览器向服务器如何发送数据

  • 附在 url 后面,如:http://localhost:8989/MyServlet/MyHttpServlet?userId=20
  • 通过表单提交
<form action="MyHttpServlet" method="post">
	你喜欢的足球队<br /><br />
	巴西<input type="checkbox" name="soccerTeam" value="Brazil" />
	德国<input type="checkbox" name="soccerTeam" value="German" />
	荷兰<input type="checkbox" name="soccerTeam" value="Holland" />
	<input type="submit" value=" 提交 " />
</form>

3)使用HttpServletRequest对象获取请求参数

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	// 一个name 对应一个值
	String userId = request.getParameter("userId");
	System.out.println("userId="+userId);
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {
	// 一个name 对应一组值
	String[] soccerTeams = request.getParameterValues("soccerTeam");
	for(int i = 0; i < soccerTeams.length; i++){
	System.out.println("team "+i+"="+soccerTeams[i]);
}

7.2 在请求域中保存数据

数据保存在请求域中,可以转发到其他Servlet或者jsp页面,这些 Servlet或者 jsp 页面就会从请求中再取出数据

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	//将数据保存到request对象的属性域中
	request.setAttribute("attrName", "attrValueInRequest");
	//两个Servlet要想共享request对象中的数据,必须是转发的关系
	request.getRequestDispatcher("/ReceiveServlet").forward(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	//从request属性域中获取数据
	Object attribute = request.getAttribute("attrName");
	System.out.println("attrValue="+attribute);
}

8、HttpServletResponse 接口

HttpServletResponse 是 ServletResponse 接口的子接口,封装了 HTTP 响应的相关信息,由Servlet 容器创建其实现类对象并传入 service(ServletRequest req, ServletResponse res) 方法中。
主要功能:

1)使用 PrintWriter 对象向浏览器输出数据
//通过PrintWriter对象向浏览器端发送响应信息
PrintWriter writer = res.getWriter();
writer.write("Servlet response");
writer.close();

2)实现请求重定向

9、字节码问题

8.1 简介

字符集 就是各种字符的集合,包括汉字,英文,标点符号等等。各国都有不同的文字、符号。这些文字符号的集合就叫字符集。
现有的字符集 ASCII、GB2312、BIG5、GB18030、Unicode 等
这些字符集,集合了很多的字符,然而,字符要以二进制的形式存储在计算机中,我们就需要对其进行编码,将编码后的二进制存入取出时我们就要对其解码,将二进制解码成我们之前的字符。这个时候我们就需要制定一套编码解码标准。否则就会导致出现混乱,也就是我们的乱码。

8.2 编码与解码

  • 编码:将字符转换为二进制数
汉字 编码方式 编码 二进制
‘中’ GB2312 D6D0 1101 0110-1101 0000
‘中’ UTF-16 4E2D 0100 1110-0010 1101
‘中’ UTF-8 E4B8AD 1110 0100-1011 1000-1010 1101
  • 解码:将二进制数转换为字符
    1110 0100-1011 1000-1010 1101 → E4B8AD → ’中’

  • 乱码:一段文本,使用 A 字符集编码,使用 B 字符集解码,就会产生乱码。
    所以解决乱码问题的根本方法就是统一编码和解码的字符集。

在这里插入图片描述

8.3 解决乱码

解决方法就是统一字符编码。

在这里插入图片描述

8.3.1 接收中文请求参数

1)POST 请求:post 请求提交了中文。在获取参数值之前,设置请求的解码格式,使其和页面保持一致。我们以后都使用 utf-8 编码,它也称作万国码,集合了基本所有的字符。

解决方法:request.setCharacterEncoding(“utf-8”);

2)GET 请求:GET 请求参数是在地址后面的。不能使用上述方法。我们需要修改 tomcat的配置文件。需要在 Server.xml 文件修改 Connector 标签,添加 URIEncoding="utf-8"属性。

在这里插入图片描述

8.3.2 向浏览器发送有中文字符的响应

向浏览器发送响应的时候,要告诉浏览器,我使用的字符集是哪个,浏览器就会按照这种方式来解码。如何告诉浏览器响应内容的字符编码方案。很简单。

解决方法:response.setContentType(“text/html;charset=utf-8”);

或者使用这两句组合:
response.setCharacterEncoding(“utf-8”);
response.setHeader(“Content-Type”, “text/html;charset=utf-8”);

我们一般使用 response.setContentType(“text/html;charset=utf-8”);


如果有收获!!! 希望老铁们来个三连,点赞、收藏、转发。
创作不易,别忘点个赞,可以让更多的人看到这篇文章,顺便鼓励我写出更好的博客

猜你喜欢

转载自blog.csdn.net/weixin_45606067/article/details/108350443