- servlet规范来自JavaEE规范的一种作用:
- 在servlet规范中,指定动态资源文件开发步骤在servlet规范中,指定Http服务器调用动态资源文件规则在servlet规范中,指定Http服务器管理动态资源文件实例对象规则
- servlet接口来自servlet规范下一个接口,这个接口存在Htpp服务器提供jar包Tomcat服务器下lib文件有一个servlet-api.jar存放servlet接口(javax.servlet.Servlet 接口)servlet规范中认为,Http服务器能调用的动态资源文件必须是一个Servlet接口实现类
创建一个java类,继承HttpServlet类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fSTtVznC-1648088943447)(C:UsersxinaoAppDataRoamingTyporatypora-user-imagesimage-20220307154356122.png)]
重写HttpServlet父类的方法:
- doGet()doPut()
将servlet接口实现类信息注册到Tomcat服务器
将servlet接口实现类路径地址交给Tomcat
myServlet com.zxy.servlet_demo.MyServlet myServlet /myServlet
网站中所有的servlet接口实现类的实例对象,只能由http服务器负责创建(不能由开发人与处理)
在默认情况下,http服务器接收到对于当前servlet接口实现类第一次请求
自动创建这个servlet接口实现类的实例对象。
手动配置情况下,可以要求http服务器在启动时自动创建某个servlet接口实现类的实例对象。
myServlet com.zxy.servlet_demo.MyServlet
在http服务器运行期间,一个servlet接口实现类只能被创建一个实例对象。
在http服务器关闭时,自动将网站中所有的servlet对象销毁。
介绍:
- HttpServletResponse接口来自servlet规范中,在Tomcat中存在于servlet-api.jar中HttpServletResponse接口实现类由Http服务器提供HttpServletResponse接口负责将doGet/doPost方法执行结果写入响应体交给浏览器开发人员习惯把HttpServletResponse接口修饰的对象称为响应对象
主要功能:
将执行结果以二进制形式写入响应体
out.write(message);
设执响应头中content-type属性值,从而控制浏览器使用对应编译器将响应体中数据解析出来
response.setContentType("text/html;charset=utf-8");
设执响应头中location属性值,将一个请求地址赋给location,控制浏览器向指定服务器发送请求
response.sendRedirect("https://www.baidu.com/");
介绍:
- HttpServletRequest接口来自servlet规范中,在Tomcat中存在于servlet-api.jar中HttpServletRequest接口实现类由Http服务器提供HttpServletRequest接口负责doGet/doPost方法运行时读取Http请求协议包中的信息开发人员习惯把HttpServletRequest接口修饰的对象称为请求对象
主要功能:
读取Http请求协议包中请求行信息
//通过请求对象,读取请求行中url信息 StringBuffer requestURL = request.getRequestURL(); //读取请求行中method信息 String method = request.getMethod(); //读取请求行中uri信息 String uri = request.getRequestURI();
读取保存在Http请求协议包中请求头/请求头中请求参数信息
request.setCharacterEncoding("utf-8");
//通过请求对象获取请求头中所以请求参数名称
Enumeration parameterNames = request.getParameterNames();
//通过参数名读取对应参数值
String value = request.getParameter("参数名");
代替浏览器向Http服务器申请资源文件的调用
在Http服务器接收到浏览器发送的Http请求协议包之后,自动为当前的Http请求协议包生成一个请求对象和响应对象
在Http服务器调用doGet/doPost方法时,会把请求对象/响应对象作为实参传递到方法,确保doGet/doPost正确执行
在Http服务器准备推送Http响应协议包之前,负责将本次请求关联的请求对象和响应对象销毁
请求对象和响应对象生命周期贯穿一次请求的处理过程
请求对象和响应对象相当于用户在服务端的代言人
前提:
- 用户可以记住网站名,但不会记住网站资源名
默认欢迎资源文件:
用户发送了一个针对某个网站的默认请求时,此时由Http服务器自动从当前网站返回的资源文件:
正常请求:
http://localhost:8080/myWeb/index.html
默认请求:
http://localhost:8080/myWeb
Tomcat对于默认欢迎资源文件定位规则:
规则位置:
Tomcat安装位置/conf/web.xml
规则命令:
index.html index.htm index.jsp
设置当前网站的默认欢迎资源位置:
规则位置:
网站/web/WEB-INF/web.xml
规则命令:
MyServlet login.html
介绍:
- 由三位数字组成的符号Http服务器推送响应包之前,根据本次请求处理情况,将Http状态码写入响应包状态行中如果Http服务器根据本次请求返回了对应资源文件,通过http状态码通知浏览器该如何处理这个结果如果Http服务器根据本次请求没有返回了对应资源文件,通过http状态码向浏览器解释不能提供服务的原因
分类:
组成:100—599:分为5类
1xx:信息,服务器收到请求,需要请求者继续执行操作
典型的如100,通知浏览器本次返回的资源文件不是一个独立的资源文件,需要浏览器接
受响应包后,继续向http服务器请求需要的其他资源文件
2xx:成功,操作被成功接收并处理
典型如200,通知浏览器本次返回的资源文件是一个独立的资源文件,浏览器接
受响应包后,不需要其他操作
3xx:重定向,需要进一步的操作以完成请求
典型如302,通知浏览器本次返回并非资源文件内容,而是一个资源文件地址,需要浏览器根据这个地址
自动发起请求索取这个资源文件
response.sendRedirect("资源文件地址");
4xx:客户端错误,请求包含语法错误,或无法完成请求
典型如404,通知浏览器,服务端里没有定位到被访问的资源文件,无法提供帮助405,通知浏览器,服务器已经定位到被访问的资源文件,但这个资源文件对于浏览器采用的请求方式不能处理
5xx:服务器错误,服务器在处理请求的过程中发生了错误
典型如500,通知浏览器,在服务端已经定位到被访问的资源文件,可以处理浏览器的请求方式,但是在处理过程中出现错误
前提条件:
某些来自浏览器的请求,往往需要服务端多个servlet系统处理,但是浏览器一次只能访问一个servlet,导致需要用户通过浏览器手动发起多次请求才能得到服务,这会增加用户获取服务难度,导致用户放弃访问。
提高用户使用体验:
无论本次请求涉及多个servlet,用户只需手动通知浏览器发起一次请求即可
调用规则:
- 重定向解决方案:请求转发解决方案:
工作原理:
- 用户第一次通过手动方式通知浏览器访问servlet,访问以后把第二个servlet方式写入到响应头的location属性中去,Tomcat把302写入状态行浏览器接收到响应包,根据302状态码,读取location属性发起第二次请求去完成任务
实现原理:
response.sendRedirect("请求地址");
特征:
- 请求地址:既可以把当前网站内部资源文件发送给浏览器,也可以把其他网站资源文件发送给浏览器请求次数:浏览器至少发送两次请求,只有第一次请求是用户手动发送,后续都是浏览器自动发送请求方式:重定向解决方案中,根据地址栏通知浏览器发起下一起请求,因此,通过通过重定向解决方案调用资源文件接受的请求方式一定是get
缺点:
- 重定向方案需要在浏览器与服务器之间进行多次往返,大量时间消耗在往返次数上,增加用户等待服务时间
原理:
用户第一次通过手动方式要求浏览器访问servlet,servlet调用完成后,通过当前请求对象代替浏览器向Tomcat发送请求,申请调用第二个servlet,Tomcat 接收到请求后,调用servlet响应请求。
实现命令:请求对象代替浏览器向Tomcat发送请求
//通过当前请求对象生成资源文件申请报告对象
RequestDispatcher dispatcher = request.getRequestDispatcher();//绝对路径/相对路径都可以
//将报告对象发给Tomcat
dispatcher.forward("当前请求对象", "当前响应对象");
优点:
- 无论本次请求涉及了多少个servlet,用户只需手动通过浏览器发送一次请求servlet之间调用发生在服务器端,节省服务器和浏览器之间往返次数,增加处理服务速度
特征:
- 请求次数:浏览器只发送一次请求请求地址:只能是当前网站内部的资源文件地址请求方式:在请求转发过程中,浏览器只发送了一个Http请求协议包,参与本次请求的所有servlet共享同一个请求协议包,因此,这些servlet接受的请求方式与浏览器发送的请求方式保持一致
- 数据共享:一个servlet工作完成后,把产生的数据交给另一个servlet使用servlet规范中提供四种数据共享方案:
ServletContext接口cookie类HttpSession接口HttpServletRequest接口
介绍:
- 接口来自servlet规范中,在Tomcat中存在于servlet-api.jar中,在Tomcat中负责提供这个接口实现类如果两个servlet来自同一网站,之间可通过网站的ServletContext实例对象实现数据共享开发人员习惯把ServletContext对象称为***全局作用域对象***
工作原理:每个网站都存在一个全局作用域对象,这个全局作用域对象相当于一个map。网站中servlet可以将数据存储到全局作用域对象,而后其他servlet都可以从全局作用域对象中取出数据使用。
生命周期:
在Http服务器启动过程,自动为当前网站在内存中创建一个全局作用域对象
在Http服务器运行过程中,一个网站只能有一个全局作用域对象
在Http服务器运行期间,全局作用域对象一直处于活跃状态
在Http服务器准备关闭时,负责将本网站全局作用域对象销毁
全局作用域对象生命周期贯穿网站整个运行期间
命令实现:
//获取当前网站全局作用域对象
ServletContext application = request.getServletContext();
//存放数据
application.setAttribute("测试", 123);
//获取当前网站全局作用域对象
ServletContext application = request.getServletContext();
//根据key获取数据
Object data = application.getAttribute("测试");
介绍:
- 一个来自servlet规范中的工具类,在Tomcat中存在于servlet-api.jar中如果两个servlet来自同一个网站,并且为同一浏览器/用户提供服务,此时可借助cookie实现数据共享cookie存放当前用户的私人数据,在共享数据过程中提高服务质量现实生活中,cookie相当于用户在服务端得到会员卡
原理:
用户通过浏览器第一次向网站发送访问请求,请求期间会创建一个cookie存储于与当前用户相关的数据,请求结束后,将cookie写入响应头交还给当前浏览器。
浏览器收到请求响应包之后,将cookie存储在浏览器缓存中,一段时间以后,用户通过同一浏览器再次向网站发送访问请求时,此时浏览器需要无条件将网站之前推送的cookie,写入请求头发送过去。此时网站就可以读取cookie中的信息。
实现命令:
//创建一个cookie对象
cookie cookie = new cookie("name", "zhaoxye");
//将cookie写入响应体
response.addcookie(cookie);
//获取浏览器返回的cookie列表
cookie[] cookies = request.getcookies();
//遍历cookie列表
Arrays.stream(cookies).forEach(item -> System.out.println(item.getName() + ":" + item.getValue()));
cookie生命周期:
在默认情况下,cookie存放在浏览器缓存中,正常浏览器关闭,cookie销毁
在手动设置情况下,可以要求浏览器将接受的cookie存放在计算机硬盘上,并且指定cookie在计算机上存活时间。存活时间内,cookie一直有效。存活时间到达,cookie自动被从硬盘上删除。
//cookie存活1分钟 cookie.setMaxAge(60);
介绍:
- 接口来自servlet规范中,在Tomcat中存在于servlet-api.jar中,其实现类由Http服务器提供如果两个servlet来自同一个网站,并且为同一浏览器/用户提供服务,此时可借助HttpSession实现数据共享开发人员习惯将HttpSession接口修饰对象称为***会话作用域对象***
HttpSession和cookie区别:
- 存储位置不同:
cookie存放在客户端HttpSession存放在服务器 存储类型:
- cookie只能存储String对象HttpSession可以存储任意类型数据对象
一个cookie对象只能存储一个共享数据HttpSession使用map集合存储共享数据,所以可以存储任意数量共享数据 参照物:
cookie相当于客户在服务端会员卡HttpSession相当于客户在服务端私人保险柜
命令实现:
//获取session
HttpSession session = request.getSession();
//存放数据
session.setAttribute("我", "一直坚持下去,绝不动摇");
//获取session
HttpSession session = request.getSession();
//获取绑定到session中所有对象名
Enumeration names = session.getAttributeNames();
//获取对应值
Object value = session.getAttribute("我");
Http服务器如何将用户和HttpSession联系起来:
cookie
getSession()和getSession(false)区别
getSession():
如果当前用户在服务端拥有session,tomcat返回如果当前用户没有session,tomcat创建一个新的session并返回 getSession(false):
如果当前用户没有session,tomcat返回null
HttpSession销毁时机:
用户与HttpSession关联时使用的cookie只能存放在浏览器中在浏览器关闭时,用户与HttpSession的关系被切断由于Tomcat无法检测浏览器何时关闭,因此浏览器关闭时不会导致Tomcat将浏览器关联的HttpSession进行销毁为了解决这个问题,Tomcat为每一个HttpSession对象设置***空闲时间***,空闲时间默认30分钟。如果当前的HttpSession对象空闲时间达到20分钟,Tomcat会认为用户已经放弃了HttpSession,将会销毁掉HttpSession
HttpSession空闲时间手动设置:
网站/web/WEB-INF/web.xml5
- 介绍:
同一个网站中,如果连个servlet之间通过servlet通过***请求转发***方式进行调用,彼此之间共享同一个请求协议包。而一个请求协议包只对一个请求对象。因此servlet之间共享同一个请求对象,此时可以利用这个请求对象在两个servlet之间实现数据共享。在请求对象实现servlet之间数据共享功能时,开发人员将请求对象称为***请求作用域对象*** 命令实现:
参考HttpServletRequest和请求转发
介绍:
一组来自于Servlet规范下的接口,共有8个接口,在Tomcat中存在于servlet-api.jar中监听器接口需要由开发人员亲自实现监听器接口用于监控***作用域对象生命周期变化时刻*** 以及***作用域对象共享数据变化时刻***
作用域对象:
在Servlet规范中,认为在服务端内存中可以在某些条件下可以为两个Servlet之间提供数据共享方案的独享,被称为作用域对象Servlet规范下作用域对象:
ServletContext:全局作用域对象HttpSession:会话作用域对象HttpServletRequest:请求作用域对象
监听器接口实现类开发规范:
根据监听的实际情况,选择对应的监听器接口实现重写监听器接口中***监听事件处理方法***在web.xml中将监听器接口实现类注册到Http服务器
ServletContextListener接口:
通过这个接口合法检测全局作用域对象初始化/销毁的时刻
监听事件处理方法:
default public void contextInitialized(ServletContextEvent sce) {}
default public void contextDestroyed(ServletContextEvent sce) {}
将监听器接口实现类注册到Tomcat:
com.example.servlet_demo.MyContextListener
ServletContextAttributeListenter接口:
通过这个接口合法检测全局作用域对象共享数据变化的时刻
监听事件处理方法:
default public void attributeAdded(ServletContextAttributeEvent event) {}
default public void attributeRemoved(ServletContextAttributeEvent event) {}
default public void attributeReplaced(ServletContextAttributeEvent event) {}
介绍:
来自于Servlet规范下的接口,在Tomcat中存在于servlet-api.jar中Filter接口实现类由开发人员负责Filter接口实现类在Http服务器调用资源文件之前,对Http服务器进行拦截
具体作用:
拦截Http服务器,检测当前请求合法性拦截Http服务器,对当前请求进行增强操作
具体开发步骤:
创建java类实现Filter接口
重写Filter接口中的doFilter方法
//获取登录用户名
String name = request.getParameter("name");
//是管理员就放行
if ("ADMIN".equals(name)){
//将拦截请求对象和响应对象交还给tomcat
chain.doFilter(request, response);
} else {
//过滤器代替Http服务器拒绝本次请求
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.write("你没有权限查看");
}
在web.xml中将过滤器注册到Http服务器
myFilter
com.example.servlet_demo.MyFilter
myFilter
MyServlet
/img/*.jpg
*.jpg
/*
恶意登录:
未经登录访问内容,或者恶意破解其余人账户
方法:
session过滤器
Servlet介绍:
由sun公司推出,为了解决用户和浏览器动态交互的问题Servlet 是一个基于 Java 技术开发的 web 组件,它运行在服务器端,由 Servlet容器管理。主要用于处理用户的请求并生成动态的信息。
Servlet接口解析:
初始化:
由servlet容器初始化servlet时调用,只有调用成功,servlet才会接受任何请求在servlet的生命周期只会调用一次入参:
config:
类型:ServletConfg说明:包含了servlet初始化时候的各项参数和配置
public void init(ServletConfig config) throws ServletException;
请求响应:
由servlet容器调用,来响应请求只有初始化成功,才能响应请求servlet容器通常在多线程servlet容器中运行,可以同时处理多个请求。因此,开发人员必须知道同步访问的所有共享资源入参:
req
类型:ServletRequest说明:定义一个向servlet提供客户端请求信息的对象 res:
类型:ServletResponse说明:定义一个对象帮助servlet向客户端发送响应
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;
销毁:
由servlet容器调用,向servlet指示servlet正在停止服务只有当servlet服务方法中所有线程都退出、超时后,才会调用该方法调用此方法后,不会再调用该服务——(此时并未真正被销毁,只是被标记为不可用,而且该服务不会再被调用)清理一些资源的占用情况,例如文件、线程,确保任何持久的状态和servlet的当前状态在内存中是同步的。
public void destroy();
获取servlet相关信息:
返回有关servlet的信息,例如作者、版本和版权。此方法返回的字符串应该是纯文本,而不是任何类型的标记(如HTML、XML等)。
public String getServletInfo();
获取ServletConfig对象:
该对象包含此servlet的初始化和启动参数该对象用于传递给init方法实现初始化该接口的实现负责存储ServletConfig对象,以便该方法可以返回它。实现这个接口的GenericServlet类已经完成了这项工作。
public ServletConfig getServletConfig();
介绍:
servlet容器在初始化期间用来向servlet传递信息的servlet配置对象。
方法:
获取servlet实例的名称:
名称可以通过服务器管理提供,在web应用程序部署描述符中分配:
@WebServlet(name = "helloServlet", value = "/hello-servlet")
MyServlet com.example.servlet_demo.MyServlet MyServlet /MyServlet
对于未注册(因此未命名)的servlet实例,它将是servlet的类名
public String getServletName();
返回ServletContext对象:
返回一个ServletContext对象,调用者使用它与servlet容器进行交互
public ServletContext getServletContext();
获取具有给定名称的初始化参数的值:
入参:
name:
类型:String说明:要获取其值的初始化参数的名称
包含初始化参数值的字符串,如果初始化参数不存在,则为null
public String getInitParameter(String name);
返回所有servlet初始化参数名称:
如果servlet没有初始化参数,则返回空枚举
以字符串对象枚举的形式返回servlet初始化参数的名称
public EnumerationgetInitParameterNames();
介绍:
定义一个通用的、独立于协议的servletGenericServlet实现Servlet和ServletConfig接口。GenericServlet可以由servlet直接扩展,但更常见的是扩展特定于协议的子类,如HttpServlet。GenericServlet使编写Servlet变得更容易。它提供了生命周期方法init和destroy的简单版本,以及ServletConfig接口中的方法的简单版本。GenericServlet还实现了在ServletContext接口中声明的log方法。
方法:
实现了空的destroy()
public void destroy() {
}
实现了默认返回为空字符串的getServletInfo()
public String getServletInfo() {
return "";
}
新增了初始化配置的init()
public void init() throws ServletException {
}
实现了ServletContext的log()
public void log(String msg) {
getServletContext().log(getServletName() + ": "+ msg);
}
public void log(String message, Throwable t) {
getServletContext().log(getServletName() + ": " + message, t);
}
还有唯一一个抽象方法service()
public abstract void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;
介绍:
提供一个要子类化的抽象类,以创建适用于网站的HTTP servletHttpServlet的子类必须重写至少一个方法,通常是以下方法之一:
doGet,如果servlet支持HTTP GET请求doPost,用于HTTP POST请求doPut,用于HTTP PUT请求doDelete,用于HTTP删除请求init和destroy,以管理在servlet生命周期内保留的资源getServletInfo,servlet使用它来提供关于自身的信息
方法;
doGet():
由服务器调用(通过服务方法),以允许servlet处理GET请求。
重写此方法以支持GET请求也会自动支持HTTP头请求。HEAD请求是一个GET请求,它在响应中不返回任何主体,只返回请求头字段。
重写此方法时,读取请求数据,写入响应头,获取响应的writer或output stream对象,最后写入响应数据。最好包括内容类型和编码。使用PrintWriter对象返回响应时,请在访问PrintWriter对象之前设置内容类型。
servlet容器必须在提交响应之前写入头,因为在HTTP中,头必须在响应主体之前发送。
在可能的情况下,设置内容长度头(使用ServletResponse.setContentLength方法),以允许servlet容器使用持久连接将其响应返回给客户端,从而提高性能。如果整个响应适合响应缓冲区,则会自动设置内容长度。
当使用HTTP 1.1分块编码(这意味着响应有一个传输编码头)时,不要设置内容长度头。
如果请求的格式不正确,doGet将返回HTTP“Bad request”消息。
入参:
req:
类型:HttpServletRequest说明:一个HttpServletRequest对象,包含客户端对servlet发出的请求 resp:
类型:HttpServletResponse说明:一个HttpServletResponse对象,包含servlet发送给客户端的响应
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_get_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
}
getLastModified():
返回HttpServletRequest对象上次修改的时间,以毫秒为单位,自1970年1月1日格林威治标准时间午夜起。如果时间未知,此方法将返回负数(默认值)。
支持HTTP GET请求并能快速确定其最后修改时间的servlet应覆盖此方法。这使得浏览器和代理缓存更有效地工作,减少了服务器和网络资源的负载。
protected long getLastModified(HttpServletRequest req) {
return -1;
}
doHead():
从受保护的服务方法接收HTTP HEAD请求并处理该请求。当客户端只想查看响应的标题(如内容类型或内容长度)时,会发送一个HEAD请求。HTTP HEAD方法计算响应中的输出字节数,以准确设置内容长度头
如果重写此方法,可以避免计算响应体,只需直接设置响应头即可提高性能
protected void doHead(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
NoBodyResponse response = new NoBodyResponse(resp);
doGet(req, response);
response.setContentLength();
}



