Servlet
文章目录
一、Servlet 概述
Servlet 就是一个运行在 web 服务器上的一个小的 java 程序(也是一个接口),用于处理从 web 客户端发送的请求并对请求做出响应
1.1 使用 Servlet
- 编写一个 Java 类实现 Servlet 接口
- 配置 Servlet
1.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"); } }
-
在 WEB-INF 中的 web.xml 配置上面的 java 类,即需要配置servlet
切换到 source 编辑 web.xml:
web.xml 中配置 servlet:
注意:servlet-mapping 中的 servlet-name 和 servlet 中的 servlet-name 必须一致 -
访问 servlet
通过 http://localhost:8081/hello 就可以访问,因为在 web.xml 中配置的访问路径是/hello
访问成功的界面:
1.3 Servlet 执行流程
执行流程:
- 在web.xml 中找到与浏览器中的地址相匹配的配置的访问路径
- 通过该访问路径找到与之映射的 servlet 的名称
- 该 servlet 名称对应 servlet 标签的 servlet 名称
- 在 servlet 标签中找到配置的 servlet类 的全路径(servlet-class)
- 这样就找到了我们写的 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](https://i-blog.csdnimg.cn/blog_migrate/9a9361edb69b8088c099c818665204cd.png)
![image-20211115100321007](https://i-blog.csdnimg.cn/blog_migrate/5d01aac0e6fd5642cd994814c450d319.png)
![image-20211115100456436](https://i-blog.csdnimg.cn/blog_migrate/ed477df3209ef77f3d199183f85092e5.png)
![image-20211115100549647](https://i-blog.csdnimg.cn/blog_migrate/6aceee4c95c078cb556edd50f6eea85a.png)
![image-20211115100549647](https://i-blog.csdnimg.cn/blog_migrate/322c6741ed63afe1ae493686d410e37f.png)
注意:在 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 节点
注意:需要给 load-on-startup 节点 传一个整数,代表 servlet 的优先级。数值越小,优先级越高。一般从2开始,因为 tomcat 的默认有个 servlet,其配置的优先级为 1
会发现,在服务器启动时 servlet 就创建了实例,不用等到在浏览器中输入地址访问 servlet 时再创建实例,节约了时间
3.3 Servlet 的访问路径的配置
3.3.1 servlet 中 url-pattern的配置
配置方式:
-
完全路径匹配
以 / 开始 如:/aaa/ServletDemo
浏览器中输入:localhost:8081/web_test/ServletDemo2 才能匹配 -
目录匹配
以 / 开始,以 * 结束(*表示匹配任意内容) 如:/aaa/*
浏览器中输入:localhost:8081/web_test/aaa/adbjojsbfhf(任意内容) 匹配
-
扩展名匹配
不能以 / 开始,以 * 开始,. 紧跟其后,代表以什么什么结尾 如:*.do
浏览器中输入:localhost:8081/web_test/servlet.abc 匹配
3.3.2 访问的优先级
完全路径匹配 > 目录匹配 > 扩展名匹配
四、servlet 中的对象
4.1 ServletConfig 对象
ServletConfig 用来获得 Servlet 的相关配置对象
4.1.1 获得ServletConfig 对象
方法:getServletConfig()
- 获取servlet 初始化参数
- 获得 ServletContext 对象
- 获得 Servlet 名称
演示:
- 配置初始化参数
- 获取参数
- 查看结果
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()
全局初始化参数配置如下:
-
读取 web 项目下的文件
之前是使用IO流就可以读取文件(java项目中)。现在是一个web项目,web项目需要发布到tomcat 下才能访问。获取 web 项目下的文件若使用传统的IO就会出现问题(原因:路径中使用的是相对路径,相对的是JRE环境)
1. ServletContext 作为域对象的 API:
- 存入数据:setAttribute()
- 获取数据:getAttribute()
- 移除数据: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");
}
}