1.Servlet介绍
Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
2.Servlet作用
Servlet专门用来接收客户端的请求,专门接收客户端的请求数据,然后调用底层service处理数据并生成结果
浏览器http请求------》tomcat服务器-------》到达servlet-----》执行doget,dopost方法----》返回数据
HTTP服务器能调用的动态资源文件必须是一个Servlet接口实现类
class Student{
//不是动态资源文件,Tomcat无权调用
}
class Teacher implements Servlet{
//合法动态资源文件,Tomcat有权利调用
Servlet obj = new Teacher();
obj.doGet()
}
3.Servlet接口实现类
(1)创建一个Java类继承与HttpServlet父类,使之成为一个Servlet接口实现类
(2)重写HttpServlet父类两个方法。doGet或doPost
(3)将Servlet接口实现类信息【注册】到Tomcat服务器
//不直接实现Servlet接口的原因
//如果开发者直接实现Servlet接口,需要重写接口中所有方法,而我们需要使用的只有service方法
//抽象类作用:将接口中不需要使用的抽象方法交给抽象类进行完成,实现类只要对接口需要的方法进行重写
public abstract class HttpServlet extends GenericServlet
//GenericServlet帮我们空实现了接口中除service外的方法
public abstract class GenericServlet implements Servlet
doGet方法处理get请求,doPost方法处理post请求
GET和POST请求方式的区别
GET 方法是默认的从浏览器向 Web 服务器传递信息的方法,它会产生一个很长的字符串,出现在浏览器的地址栏中。如果您要向服务器传递的是密码或其他的敏感信息,请不要使用 GET 方法。GET 方法有大小限制:请求字符串中最多只能有 1024 个字符。
POST 方法打包信息的方式与 GET 方法基本相同,但是 POST 方法不是把信息作为 URL 中 ? 字符后的文本字符串进行发送,而是把这些信息作为一个单独的消息。消息以标准输出的形式传到后台程序。
//重写方法快捷键:ctrl+O
//HttpServlet重写的service方法会判断调用get还是post
//模板设计模式:通过父类决定在何种情况下调用子类方法
public class OneServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
在web.xml中注册Servlet信息
<servlet>
<servlet-name>myservlet</servlet-name>
<servlet-class>Servlet路径</servlet-class>
</servlet>
<!--请求别名-->
<servlet-mapping>
<servlet-name>myservlet</servlet-name>
<url-pattern>/别名</url-pattern>
</servlet-mapping>
4.Servlet对象生命周期
由谁创建: 所有的Servlet接口实现类的实例对象,只能由Http服务器负责额创建。开发人员不能手动创建Servlet接口实现类的实例对象
创建时间: 在默认的情况下,Http服务器接收到对于当前Servlet接口实现类第一次请求时自动创建这个Servlet接口实现类的实例对象(可以手动配置 改变创建时间)
//可以手动配置 改变创建时间
<load-on-startup>1<load-on-startup><!--填写一个大于0的整数即可-->
创建个数: 在HTTP服务器运行期间,一个Servlet只能创建出一个实例化对象
销毁时间: 在HTTP服务器关闭时,自动销毁所有Servlet对象
5.HttpServletResponse接口
作用: HttpServletResponse接口负责将doGet/doPost方法执行结果写入到【响应体】交给浏览器
(1) 将执行结果以二进制形式写入到【响应体】
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
//执行结果写入响应体
String result="Hello";//执行结果
//获取输出流
PrintWriter out = resp.getWriter();
//将执行结果以二进制写入到响应体
out.print(result);
//Tomcat负责关闭输出流
}
(2) 设置响应头中[content-type]属性值,从而控制浏览器使用 对应编译器将响应体二进制数据编译为【文字,图片,视频,命令】
resp.setContentType("text/html;charset=utf-8");
(3) 设置响应头中【location】属性,将一个请求地址赋值给location. 从而控制浏览器向指定服务器发送请求
String result="http://www.baidu.com";//执行结果
//将地址值赋值给响应头中location属性
resp.sendRedirect(result);
响应对象: 将HttpServletResponse接口修饰的对象称为【响应对象】
6.HttpServletRequest接口
作用: HttpServletRequest接口负责在doGet/doPost方法运行时读取Http请求协议包中信息
(1)可以读取Http请求协议包中【请求行】信息
//通过请求对象,读取请求行中的url
String url = req.getRequestURL().toString();
//通过请求对象,读取请求行中的method
String method = req.getMethod();
(2)可以读取保存在Http请求协议包中【请求头】或则【请求体】中请求参数信息
浏览器get请求把参数保存在请求头,Tomcat会负责解码,默认utf-8字符集
Post请求将参数保存在请求体,当前对象(req)负责解码,默认ISO-8859-1
//获取请求参数名称
Enumeration paramNames=req.getParameterNames();
while(paramNames.hasMoreElements()){
String paramName=(String) paramNames.nextElement();
}
}
(3)可以代替浏览器向Http服务器申请资源文件调用
将HttpServletRequest接口修饰的对象称为【请求对象】
7.请求对象和响应对象生命周期
(1).在Http服务器接收到浏览器发送的【Http请求协议包】之后,自动为当前的【Http请求协议包】生成一个【请求对象】和一个【响应对象】
(2).在Http服务器调用doGet/doPost方法时,负责将【请求对象】和【响应对象】作为实参传递到方法,确保doGet/doPost正确执行
(3).在Http服务器准备推送Http响应协议包之前,负责将本次请求关联的【请求对象】和【响应对象】 销毁
8.状态码
Http服务器在推送响应包之前,根据本次请求处理情况将Http状态码写入到响应包中【状态行】上
作用:
如果Http服务器针对本次请求,返回了对应的资源文件。
通过Http状态码通知浏览器应该如何处理这个结果
如果Http服务器针对本次请求,无法返回对应的资源文件 通过Http状态码向浏览器解释不能提供服务的原因
9.多个Servlet之间调用规则
9.1 重定向解决方案
原理: 用户第一次通过【手动方式】通知浏览器访问OneServlet。
OneServlet工作完毕后,将TwoServlet地址写入到响应头
location属性中,导致Tomcat将302状态码写入到状态行。
在浏览器接收到响应包之后,会读取到302状态。此时浏览器
自动根据响应头中location属性地址发起第二次请求,访问
TwoServlet去完成请求中剩余任务
//重定向
response.sendRedirect("请求地址")
重定向解决方案特征:
(1)请求地址: 既可以把当前网站内部的资源文件地址发送给浏览器 (/网站名/资源文件名) 也可以把其他网站资源文件地址发送给浏览器(http:// ip地址:端口号 / 网站名 / 资源文件名)
(2)请求次数: 浏览器至少发送两次请求,但是只有第一次请求是用户手动发送。后续请求都是浏览器自动发送的。
(3) 请求方式:重定向解决方案中,通过地址栏通知浏览器发起下一次请求,因此通过重定向解决方案调用的资源文件接收的请求方式一定是【GET】
(4).缺点: 重定向解决方案需要在浏览器与服务器之间进行多次往返,大量时间消耗在往返次数上,增加用户等待服务时间
9.2 请求转发解决方案
原理: 用户第一次通过手动方式要求浏览器访问OneServlet。OneServlet工作完毕后,通过当前的请求对象代替浏览器向Tomcat发送请求,申请调用TwoServlet。Tomcat在接收到这个请求之后,自动调用TwoServlet来完成剩余任务
RequestDispatcher report = request.getRequestDispatcher("/资源文件名");
report.forward(当前请求对象,当前响应对象)
特征
(1)请求次数: 在请求转发过程中,浏览器只发送一次请求
(2)请求地址: 只能向Tomcat服器申请调用当前网站下资源文件地址request.getRequestDispathcer("/资源文件名")
(3)请求方式: 在请求转发过程中,浏览器只发送一个了个Http请求协议包。参与本次请求的所有Servlet共享同一个请求协议包,因此这些Servlet接收的请求方式与浏览器发送的请求方式保持一致
10.Servlet数据共享
.Servlet规范中提供四种数据共享方案
10.1 ServletContext接口
ServletContext对象称为【全局作用域对象】
使用场景:两个Servlet来自于同一个网站
工作原理:
每一个网站都存在一个全局作用域对象。这个全局作用域对象【相当于】一个Map.在这个网站中OneServlet可以将一个数据存入到全局作用域对象,当前网站中其他Servlet此时都可以从全局作用域对象得到这个数据进行使用
全局作用域对象生命周期:
1)在Http服务器启动过程中,自动为当前网站在内存中创建一个全局作用域对象
2)在Http服务器运行期间时,一个网站只有一个全局作用域对象
3)在Http服务器运行期间,全局作用域对象一直处于存活状态
4)在Http服务器准备关闭时,负责将当前网站中全局作用域对象进行销毁处理
OneServlet{
public void doGet(HttpServletRequest request,HttpServletResponse response){
//1.通过【请求对象】向Tomcat索要当前网站中【全局作用域对象】
ServletContext application = request.getServletContext();
//2.将数据添加到全局作用域对象作为【共享数据】
application.setAttribute("key1",数据)
}
}
TwoServlet{
public void doGet(HttpServletRequest request,HttpServletResponse response){
//1.通过【请求对象】向Tomcat索要当前网站中【全局作用域对象】
ServletContext application = request.getServletContext();
//2.从全局作用域对象得到指定关键字对应数据
Object 数据 = application.getAttribute("key1");
}
}
10.2 Cookie类
使用场景:两个Servlet来自于同一个网站,并且为同一个浏览器/用户提供服务
原理:
用户通过浏览器第一次向MyWeb网站发送请求申请OneServlet。 OneServlet在运行期间创建一个Cookie存储与当前用户相关数据, OneServlet工作完毕后,【将Cookie写入到响应头】交还给当前浏览器。 浏览器收到响应响应包之后,将cookie存储在浏览器的缓存, 一段时间之后,用户通过【同一个浏览器】再次向【myWeb网站】发送请求申请TwoServlet时。 【浏览器需要无条件的将myWeb网站之前推送过来的Cookie,写入到请求头】发送过去, 此时TwoServlet在运行时,就可以通过读取请求头中cookie中信息,得到OneServlet提供的共享数据
OneServlet{
public void doGet(HttpServletRequest request,HttpServletResponse resp){
//1.创建一个cookie对象,保存共享数据(当前用户数据)
Cookie card = new Cookie("key1","abc");
Cookie card1= new Cookie("key2","efg");
//cookie相当于一个map
//一个cookie中只能存放一个键值对
//这个键值对的key与value只能是String
//键值对中key不能是中文
//2.将cookie写入到响应头,交给浏览器
resp.addCookie(card);
resp.addCookie(card1)
}
}
TwoServlet{
public void doGet(HttpServletRequest request,HttpServletResponse resp){
//1.调用请求对象从请求头得到浏览器返回的Cookie
Cookie cookieArray[] = request.getCookies();
//2.循环遍历数据得到每一个cookie的key 与 value
for(Cookie card:cookieArray){
String key = card.getName(); 读取key "key1"
Strign value = card.getValue();读取value "abc"
}
}
}
在默认情况下,Cookie对象存放在浏览器的缓存中。因此只要浏览器关闭,Cookie对象就被销毁掉
10.3 HttpSession接口
HttpSession接口修饰对象称为【会话作用域对象】
使用场景:两个Servlet来自于同一个网站,并且为同一个浏览器/用户提供服务,此时借助于HttpSession对象进行数据共享
HttpSession 与 Cookie 区别:
存储位置:
Cookie:存放在客户端计算机(浏览器内存/硬盘)
HttpSession:存放在服务端计算机内存
数据类型:
Cookie对象存储共享数据类型只能是String
HttpSession对象可以存储任意类型的共享数据Object
数据数量:
一个Cookie对象只能存储一个共享数据
HttpSession使用map集合存储共享数据,所以可以存储任意数量共享数据
OneServlet将数据传递给TwoServlet
OneServlet{
public void doGet(HttpServletRequest request,HttpServletResponse response){
//1.调用请求对象向Tomcat索要当前用户在服务端的私人储物柜
HttpSession session = request.getSession();
//2.将数据添加到用户私人储物柜
session.setAttribute("key1",共享数据)
}
}
TwoServlet{
public void doGet(HttpServletRequest request,HttpServletResponse response){
//1.调用请求对象向Tomcat索要当前用户在服务端的私人储物柜
HttpSession session = request.getSession();
//2.从会话作用域对象得到OneServlet提供的共享数据
Object 共享数据 = session.getAttribute("key1");
}
}
10.4 HttpServletRequest接口
实现HttpServletRequest的对象被称为【请求作用域对象】
在同一个网站中,如果两个Servlet之间通过【请求转发】方式进行调用, 彼此之间共享同一个请求协议包。而一个请求协议包只对应一个请求对象 因此servlet之间共享同一个请求对象,此时可以利用这个请求对象在两个 Servlet之间实现数据共享
OneServlet{
public void doGet(HttpServletRequest req,HttpServletResponse response){
//1.将数据添加到【请求作用域对象】中attribute属性
req.setAttribute("key1",数据); //数据类型可以任意类型Object
//2.向Tomcat申请调用TwoServlet req.getRequestDispatcher("/two").forward(req,response)
}
}
TwoServlet{
public void doGet(HttpServletRequest req,HttpServletResponse response){
//从当前请求对象得到OneServlet写入到共享数据
Object 数据 = req.getAttribute("key1");
}
}
11.监听器
作用: 监听器接口用于监控【作用域对象生命周期变化时刻】以及【作用域对象共享数据变化时刻】
Servlet规范下作用域对象:
ServletContext: 全局作用域对象
HttpSession : 会话作用域对象
HttpServletRequest:请求作用域对象
监听器接口实现类开发步骤
(1)根据监听的实际情况,选择对应监听器接口进行实现
(2)重写监听器接口声明【监听事件处理方法】
(3)在web.xml文件将监听器接口实现类注册到Http服务器
12.过滤器
Filter接口在Http服务器调用资源文件之前,对Http服务器进行拦截
作用:
(1)拦截Http服务器,帮助Http服务器检测当前请求合法性 (2)拦截Http服务器,对当前请求进行增强操作
Filter接口实现类开发步骤
(1)创建一个Java类实现Filter接口
(2)重写Filter接口中doFilter方法
(3)web.xml将过滤器接口实现类注册到Http服务器