javaweb3
关于转发
-
-
转发(一次请求)
-
//第一步:获取请求转发器对象 RequestDispatcher dispatcher = request.getRequesDispatcher("/b"); //第二步:调用转发器的forward方法完成跳转/转发 dispatcher.forward(request,response); //第一步和第二步联合: request.getRequestDispatcher("路径").forward(request,response);
-
-
-
两个Servle怎么共享数据?
-
将数据放到request域当中,然后AServlet转发到BServlet,保证AServlet和BServlet在同一次请求中,这样就可以做到两个Servlet,或者多个Servlet共享同一份数据。
-
-
转发的下一个资源必须是一个Servlet吗?
-
不一定,只要是Tomcat服务器当中的合法资源,都是可以转发的。例如:html...
-
注意:转发的时候,路径的写法要注意,转发的路径以 "/" 开始,不加项目名。
-
-
关于request对象中两个非常容易混淆的方法:
-
//通过key获取value(获取请求域的值) String username = request.getParameter("username"); //之前一定是执行过:request.setAttribute("name",new Object()); //从request域中根据name获取数据 Object obj = request.getAttribute("name"); //以上两个方法的区别是什么? //第一个方法:获取的是用户在浏览器上提交的数据。 //第二个方法:获取的是请求域当中绑定的数据。
-
-
HttpServletRequest接口的其它常用方法:
-
//获取客户端的IP地址 String remoteAddr = request.getRemoteAddr(); //get请求在请求行上提交数据。 //post请求在请求体上提交数据。 //设置请求体的字符集。(这种方式不能解决get请求的乱码问题) //注意:tomcat10之后,request请求体当中的字符集默认就是utf-8,不需要设置字符集,不会出现乱码问题。 request.setCharacterEncoding("utf-8"); //在tomcat9之前(包括9),响应中文也是有乱码的,解决如下: response.serContentType("text/html;charset=UTF-8"); //tomcat10不需要 //动态获取用户根路径(使用较多) String contextPath = request.getContextPath(); //获取请求方式 String method = request.getMethod(); //获取请求的URI String requestURI = request.getRequestURI(); //获取servlet path(除去项目名的路径) String servletPath = request.getServletPath();
-
在一个web应用中应该如何完成资源的跳转
-
在一个web应用中通过两种方式,可以完成资源的跳转:
-
第一种:转发
-
第二种:重定向
-
-
转发和重定向有什么区别?
-
代码上有什么区别?
-
转发
-
//获取请求转发器对象 RequestDispatcher dispatcher = request.getRequestDispatcher("/dept/list"); //调用请求转发器对象的forward方法完成转发 dispatcher.forward(request,response); //合并代码 request.getRequestDispatcher("/dept/list").forward(request,response); //转发的时候是一次请求,不管转发了多少次,都是一次请求。 //AServlet转发到BServlet,再转发到CServlet,不管转发了多少次,都在同一个request当中。 //因为调用forward方法的时候,会将当前的request和response对象传递给下一个Servlet。
-
-
重定向
-
//注意:路径上要加一个项目名,因为重定向是浏览器自主的发送一个全新的请求 //只要是浏览器发送的请求,必须加项目名。 response.sendRedirect("/oa/dept/list");
-
-
-
形式上有什么区别?
-
转发(一次请求)
-
在浏览器地址栏上发送的请求是:http://localhost:8080/servlet03/a,最终请求结束后,浏览器地址栏上的地址还是这个,没变。
-
-
重定向(两次请求)
-
在浏览器地址栏上发送的请求是:http://localhost:8080/servlet/a,最终在浏览器地址栏上显示的地址是:http://localhost:8080/servlet/b
-
-
-
转发和重定向的本质区别?
-
转发:是由WEB服务器来控制的。A资源跳转到B资源,这个跳转动作是Tomcat服务器内部完成的。
-
重定向:是浏览器完成的。具体跳转哪个资源,是浏览器说了算。
-
-
-
转发和重定向应该如何选择?什么时候使用转发,什么时候使用重定向?
-
如果上一个Servlet当中向request域当中绑定了数据,希望下一个Servlet当中把request域里面的数据取出来,使用转发机制。
-
剩下的所有请求均使用重定向。(使用较多)
-
使用注解
-
在Servlet类上使用:@WebServlet
-
@WebServlet注解中有哪些属性呢?
-
name属性:用来指定Servlet的名字。等同于:<servlet-name>
-
urlPatterns属性:用来指定Servlet的映射路径。可以指定多个字符串。<url-pattern>
-
loadOnStartUp属性:用来指定在服务器启动阶段是否加载该Servlet。等同于:<load-on-startup>
-
value属性:这个value属性和urlPatterns属性一致,都是用来指定Servlet的映射路径的。
-
注意:
-
不是必须将所有属性写上,只需提供需要的。
-
当注解的属性是一个数组,并且数组中只有一个元素,花括号可以省略
-
如果注解的属性名是value的话,属性名也可以省略
-
-
-
注解对象的使用格式:
-
@注解名称(属性名=属性值,属性名=属性值,....)
-
JSP
-
jsp实际上就是一个Servlet
-
index.jsp访问的时候,会自动翻译生成index jsp.java,会自动编译生成index jsp.class,那么index jsp这就是一个类。
-
访问index.jsp,实际上执行的是index jsp.class中的方法。
-
index jps类继承HttpJspBase,而HttpJspBase类继承的是HttpServlet。所以index.jsp类就是一个Servlet类。
-
jsp的生命周期和Servlet生命周期完全相同。
-
jsp和servlet都是假单例的。
-
-
JSP是什么?
-
JSP是Java程序。(JSP本质还是一个Servlet)
-
JSP是:JavaServlet Pages的缩写。(基于Java语言实现的服务器端的页面)
-
Servlet是JavaEE的13个子规范之一,那么JSP也是JavaEE的13个子规范之一。
-
JSP是一套规范。所有的web容器/web服务器都是遵循这套规范的,都是按照这套规范进行的 “翻译”
-
-
在jsp中指定编码格式:
//表示响应的内容类型是text/html,采用的字符集是utf-8。 <%@page contentType="text/html;charset=UTF-8" %>
-
在jsp中编写Java程序
<% Java语句; %> //写在方法区中的Java代码 <%! %> //写在类体中的Java代码(很少用,存在线程安全问题)
-
这个符号当中编写的被视为Java程序,被翻译到Servlet类的service方法内部。
-
要注意编写方法的规范。(和Java中编写方法一致)
-
在service方法当中编写的代码是有顺序的,方法体当中的代码要遵循自上而下的顺序逐行执行。
-
在同一个jsp中,<%%>可以出现多个。
-
-
JSP的专业注释
<%-- JSP的专业注释,不会被翻译到Java源代码当中。 --%>
-
JSP的输出语句
//向浏览器输出一个Java变量 <% String name = "tzw"; out.write("name =" + name);%> //注意:以上代码中的out是JSP的九大内置对象之一。只能在service方法的内部使用。 <%= %> //这个符号代表的是-->out.print();在方法体里输出 //注意:<% %>里面不能再添加<% %>
-
JSP中out.write()和out.print()的区别:
-
out对象的类型是JspWrite。JspWrite继承了java.io.Write类。
-
print方法是子类JspWrite,write是Write类中定义的方法。
-
重载的print方法可以将各种数据类型的数据转换成字符串的形式输出,而重载的write方法只能输出字符、字符数组和字符串等与字符相关的数据。
-
JspWrite类型的out对象使用print方法和write方法都能输出字符串,但是,如果字符串对象的值为null时,print方法将输出内容为“null”的字符串,而write方法则是抛出NullPointerException异常。
-
-
JSP本质上是一个Servlet,那么JSP和Servlet的区别是什么?
-
职责不同
-
servlet的职责:收集数据。(Servlet的强项是逻辑处理,业务处理,然后连接数据库,获取 / 收集数据)
-
JSP的职责:展示数据。(JSP的强项是做数据的展示)
-
-
-
JSP的指令
-
指令的作用:指导JSP的翻译引擎如何工作。(指导当前JSP翻译引擎如何翻译JSP文件)
-
指令包括哪些?
-
include指令(基本不用)
-
taglib指令
-
page指令
-
-
指令的使用语法
-
<%@指令名 属性名=属性值 属性名=属性值 属性名=属性值...%>
-
-
page指令中有哪些常用的属性?
-
<%@page session="true|false" %> true表示启用JSP的内置对象session,表示一定启动session对象。没有session对象则创建 如果没有设置,默认值就是session="true" session="false"表示不启动内置对象session。当前JSP页面中无法使用内置对象session
-
<%@page contextType="text/json;charset=UTF-8" %> contextType属性用来设置响应的内容类型
-
<%@page pageEncoding=UTF-8 %> 表示设置响应时采用的字符集
-
<%@page import="java.util.List,java.util.Date,java.util.ArrayList" %> import语句
-
<%@page errorpage="/error.jsp" %> 当前页面出现异常之后,跳转到error.jsp页面
-
<%@page isErrorpage="true" %> 表示启用JSP九大内置对象之一:exception 打印异常信息:exception.printStackTrace(); //通常写在errorpage.jsp页面 默认值是false
-
-
-
JSP的九大内置对象
-
jakarta.servlet.jsp.PageContext pageContext 页面作用域
-
jakarta.servlet.http.HttpServletRequest request 请求作用域
-
jakarta.servlet.http.HttpSession session 会话作用域
-
jakarta.servlet.ServletContext application 应用作用域
-
pageContext < request < session < application
-
四个作用域都有:setAttribute、getAttribute、removeAttribute方法
-
以上作用域使用原则:尽可能使用小的域
-
-
java.lang.Throwable exception
-
jakarta.servlet.ServletConfig config
-
java.lang.Object page(就是this,当前的servlet对象)
-
jakarta.servlet.jsp.JspWriter out(负责输出)
-
jakarta.servlet.http.HttpServletResponse response(负责响应)
关于B/S结构系统的会话机制(session机制)
-
什么是会话(session)?
-
用户打开浏览器,进行一系列操作,然后最终将浏览器关闭,这个过程叫做:一次会话。
-
会话在服务器端也有一个对应的Java对象,叫做:session。
-
一个会话当中包含多次请求。
-
在Java的servlet规范中,session对应的类名是:HttpSession(jakarta.servlet.http.HttpSession)
-
session机制实际上是一个规范,不同的语言对这种会话机制都有实现。
-
session对象最主要的作用是:保存会话状态。
-
-
为什么需要session对象来保存会话状态?
-
因为HTTP协议是一种无状态协议。
-
什么是无状态?
-
请求的时候,B和S是连接的,但是请求结束后,连接就断了。
-
为什么要这样做?因为这样的无状态协议,可以降低服务器压力。
-
只要B和S断开了,那么关闭浏览器这个动作,服务器是不知道的。
-
-
-
为什么不使用request对象保存会话状态?为什么不使用ServletContext对象保存会话状态?
-
request.setAttribute()存,request.getAttribute()取,ServletContext也有这个方法。request是请求域,ServletContext是应用域。
-
request是一次请求一个对象。
-
ServletContext对象是服务器启动的时候创建,服务器关闭的时候销毁,这个ServletContext对象只有一个。(域太大)
-
request请求域(HttpServletRequest)、session会话域(HttpSession)、application域(ServletContext)
-
request < session < application
-
他们三个域的公共方法:
-
setAttribute(向域中绑定数据)
-
getAttribute(从域当中获取数据)
-
removeAttribute(移除域当中的数据)
-
-
使用原则:尽量使用小的域。
-
-
session对象的实现原理
-
HttpSession session = request.getSession();
-
张三访问的时候获取的session对象就是张三的,李四访问的时候获取的session对象就是李四的。
-
-
session怎么获取?
//从服务器上获取当前的session对象,如果没有则新建 HttpSession session = request.getSession(); //从服务器上获取当前对象,如果获取不到则不会新建,返回null(相当于禁用session) HttpSession session = request.getSession(false);
-
session实现原理
-
JSESSIONID=xxxxx 这是以Cookie的形式保存在浏览器的内存中的。浏览器只要关闭,这个Cookle就没有了。
-
session列表是一个Map,map的key是sessionid,map的value是session对象。
-
用户第一次请求,服务器生成session对象,同时生成id,将id发送给浏览器。
-
用户第二次请求,自动将浏览器内存中的id发送给服务器,服务器根据id查找session对象。
-
关闭浏览器,内存消失,cookie消失,sessionid消失,会话等同于结束。
-
-
为什么关闭浏览器,会话结束?
-
关闭浏览器之后,浏览器中保存的sessionId消失,下次重新打开浏览器之后,浏览器缓存中没有这个sessionId,自然找不到服务器中对应的session对象,session对象找不到等同于会话结束。
-
-
session什么时候被销毁?
-
一种销毁:是超时销毁
-
一种销毁:是手动销毁
-
session.invalidate();
-
-
-
Cookie禁用了,session还能找到吗?
-
cookie禁用是什么意思?服务器正常发送cookie给浏览器,但是浏览器不要了,拒收了,并不是服务器不发了。
-
找不到了,每一次请求都会获取到新的session对象。
-
cookie禁用了,session机制还能实现吗?
-
可以,需要使用URL重写机制。(在地址后面添加;jsessionid=12D1212)
-
URL重写机制会提高开发者的成本。开发人员在编写任何请求路径的时候,后面都要添加一个sessionid,给开发带来了很大的难度,很大的成本。所以大部分网站禁用了cookie,就不能用了。
-
-
Cookie
-
session的实现原理中,每一个session对象都会关联一个sessionid,例如:
-
JSESSIONID=B1B9FBE8076BE4E01F414A8BE8056119
-
以上这个键值对数据就是cookie对象。
-
对于session关联的cookie来说,这个cookie是被保存在浏览器的 “运行内存” 当中。只要浏览器不关闭,用户再次发送请求的时候,会自动将运行内存中的cookie发送给服务器,例如,这个cookie:JSESSIONID=B1B9FBE8076BE4E01F414A8BE8056119就会再次发送给服务器。服务器就是根据这个值来找对应的session对象的。
-
-
cookie保存在什么地方?浏览器什么时候发送cookie,发送哪些cookie给服务器?
-
cookie最终是保存在浏览器客户端上的。
-
可以保存在运行内存中(浏览器只要关闭cookie就消失了)
-
也可以保存在硬盘文件中(永久保存)
-
-
当第一次request的时候,服务器接收并创建cookie;用户第二次request的时候,浏览器发送请求并携带cookie一起发送给服务器。
-
一个url对应一个cookie。(一对多)
-
-
cookie有什么用?
-
cookie和session机制都是为了保存会话状态
-
cookie是将会话状态保存在浏览器客户端上
-
session是将会话状态保存在服务器端上。(session对象是存储在服务器上)
-
-
为什么要有cookie和session机制呢?
-
因为http协议是无状态、无连接协议
-
-
cookie机制和session机制都不属于Java机制,实际上cookie机制和session机制都是HTTP协议的一部分。PHP开发中也有cookie和session机制,只要是做web开发,cookie和session机制都是需要的。
-
HTTP协议中规定:任何一个cookie都是由name和value组成的。name和value都是字符串类型的。
-
在Java的servlet中,提供了一个Cookie类来专门表示cookie数据。jakar.servlet.http.Cookie;
-
java程序怎么把cookie数据发送给浏览器?response.addCookie(cookie);
-
在HTTP协议中是这样规定的:当浏览器发送请求的时候,会自动携带该path下的cookie数据给服务器。
-
关于cookie的有效时间
-
怎么用Java设置cookie的有效时间?
-
cookie.setMaxAge(60*60);//设置cookie在一小时之后失效 //如果设置有效时间为0,则表示cookie被删除。主要应用在删除浏览器上的同名cookie //设置cookie的有效时间 <0 ,表示该cookie不会被存储。(表示不会被存储在硬盘文件中,会放在浏览器运行内存当中。和不调用setMaxAge是同一效果)
-
-
没有设置有效时间:默认保存在浏览器运行内存中,浏览器关闭则cookie消失。
-
只要设置cookie的有效时间>0,这个cookie一定会存储到硬盘文件当中。
-
设置cookie的关联路径方法:cookie.setPath(“路径名”);
-
关于cookie的path,cookie关联的路径:
-
假设现在发送的请求路径是:"http://localhost:8080/servlet/cookie/generate" 生成的cookie,如果cookie没有设置path,默认的path是什么?
-
默认的path路径:http://localhost:8080/servlet/cookie 以及它的子路径
-
也就是说,以后只要浏览器的请求路径是 http://localhost:8080/servlet/cookie 这个路径以及这个路径以下的子路径,cookie都会被发送到服务器。
-
-
-
手动设置cookie的path
cookie.setPath("/servlet"); //表示只要是这个servlet项目的请求路径,都会提交这个cookie给服务器。
-
浏览器发送cookie给服务器了,服务器中的Java程序怎么接收?
Cookie[] cookies = request.getCookies(); //这个方法可能返回null if(cookies != null){ for(Cookie cookie : cookies){ String name = cookie.getName(); String name = cookie.getValue(); } }
EL表达式
-
EL表达式
-
Expression Language(表达式语言)
-
EL表达式可以代替JSP中的Java代码,让JSP文件中的程序看起来更加整洁、美观
-
EL表达式归属于JSP
-
EL表达式只能取,不能存。
-
-
EL表达式在JSP中的主要作用:
-
从某个域中取出数据
-
将取出的数据转换成字符串
-
将字符串输出到浏览器
-
-
EL表达式基本的语法格式:
-
${表达式}
-
-
EL表达式的使用:
<% //创建user对象 User user = new User(); user.setUsername("mo-yu-jina"); user.setpassword("0826"); //将User对象存储到某个域当中,因为EL表达式只能从某个范围中取数据 //数据是必须存储到四大域之中。 request.setAttritube("userObj",user); %> <%--使用EL表达式取--%> ${userObj} 等同于Java代码:<%=request.getAttritube("userObj")%> 面试题: ${abc} 和 ${"abc"}的区别是什么? ${abc}:表示从某个域中取出数据,并且被取出的这个数据的name是“abc“,之前一定有这样的代码:域.setAttribute("abc",对象); ${"abc"}:表示直接将"abc"当作普通字符串输出到浏览器。不会从某个域中取数据。 ${userObj}底层: 从域中取数据,取出user对象,然后调用user对象的toString方法,转换成字符串,输出到浏览器。 <%--如果想输出对象的属性值,怎么办?--%> ${userObj.username} ${userObj.password} 使用EL取出数据的前提是属性有get()方法。 如果没有get()方法则报异常。报500错误。 EL还有一种取数据的方式:(当name中有特殊符号(比如".")时使用这种方式) ${userObj["username"]} 取user的username,注意[]当中的需要加双引号 如果[]里面没有加双引号的话,会将其看作变量。加了双引号,则去找user对象的username属性。 <%--在没有指定范围的前提下,EL表达式优先从小范围中取数据--%> 在EL表达式中可以指定范围来读取数据 EL表达式中有4个隐含的隐式的范围对象 pageScope requestScope sessionScope applicationScope <%--在同名的情况下取出不同域中的数据--%> ${pageScope.data} ${requestScope.data} ${sessionScope.data} ${application.data} 数组和集合都是用下标取出数据: ${myList} //调用List集合的toString方法 ${myList[0]} //求出第一个数据 ${myList[1]} //取出第二个数据 ...以此类推.... 注意:set集合没有下标。
-
忽略EL表达式:
-
<%@page isELIgnored="true" %> //这是全局控制
-
如果是false,则表示不忽略EL表达式(默认值)
-
可以使用反斜杠进行局部控制:
\${username} 这样也可以忽略EL表达式
-
-
使用EL表达式获取应用的根路径
-
${pageContext.request.contextPath}
-
-
EL表达式的常用隐式对象:
-
pageContext
应用的根路径:${pageContext.request.contextPath}
-
param
爱好:${param.aihao} //获取的是请求参数一维数组当中的第一个元素
-
paramValues
爱好:${paramValues.aihao[0],paramValues.aihao[1],paramValues.aihao[2]} //获取数组中的元素
-
initParam
-
-
EL运算符:
-
在EL表达式中,"+"运算符只能做求和运算,不会进行字符串拼接操作。当两边不是数字的时候,一定会转换成数字,转不成数组就报错。NumberFormatException。
-
EL表达式当中的 "==" 调用了重写的equals方法。(EL中还有一个运算符 eq ,和这个一样)
-
${empty param.username} 判断是否为空
-
JSTL标签库
-
什么式JSTL标签库?
-
Java Standard Tag Lib(Java标准的标签库)
-
JSTL标签库通常结合EL表达式一起使用,目的式让JSP中的Java代码消失。
-
标签是写在JSP中的,但实际上最终还是要执行对应的Java程序。(Java程序在jar包中)
-
-
JSTL的核心标签库
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-
JSTL标签的原理
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 以上uri后面的路径实际上指向了一个xxx.tld文件。 tld文件实际上是一个xml配置文件。 在tld文件中描述了“标签”和“Java类”之间的关系。 以上核心标签库对应的tld文件是:c.tld文件。 它在jakarta.servlet.jsp.jstl-2.0.0.jar里面META-INF目录下,有一个c.tld文件。
-
配置文件tld解析
<tag> <description>对该标签的描述</description> <name>catch</name> //标签的名字 <tag-class>org.apache.taglibs.standard.tag.common.core.CatchTag</tag-class> //标签对应的Java类 <body-content>JSP</body-content> //标签体当中可以出现的内容,如果是JSP,就表示标签体中可以出现符合JSP所有语法的代码。例如EL表达式。 <attribute> <description> 对这个属性的描述 </description> <name>var</name> //属性名 <required>false</required> //false表示该属性不是必须的。true表示该属性是必须的。 <rtexprvalue>false</rtexprvalue> //这个描述说明了该属性是否支持EL表达式。false表示不支持,true表示支持。 </attribute> </tag> <c:catch var=""> JSP... </c:catch>
Filter过滤器
-
Filter是什么,有什么用,执行原理是什么?
-
Filter是过滤器
-
Fiter可以写在Servlet这个目标程序执行之前添加代码。也可以在目标Servlet执之后添加代码。之前之后都可以添加过滤规则。
-
一般情况下,都是在过滤器当中编写公共代码。
-
-
过滤器的写法:
-
第一步:编写一个Java类实现一个接口:jakarta.servlet.Filter。并且实现这个接口中的所有方法。
-
init方法:在Filter对象第一次被创建之后调用,并且只调用一次。
-
doFilter方法:只要用户发送一次请求,则执行一次。发送N次请求,则执行N次。在这个方法中编写过滤规则。
-
destroy方法:在Filter对象被释放/销毁之前调用,并且只调用一次。
-
-
第二步:在web.xml文件中对Filter进行配置。
<filter> <filter-name>filter2</filter-name> <filter-class>com.myself.javaweb.servlet.Filter2</filter-class> </filter> <filter-mapping> <filter-name>filter2</filter-name> <url-pattern>*.do</url-pattern> </filter-mapping>
或者使用注解: @WebFilter({"*.do"}) //不推荐使用注解,因为后续更改过滤器执行顺序不方便,会修改源代码
-
-
注意:
-
Servlet对象默认情况下,在服务器启动的时候是不会新建对象的。
-
Filter对象默认情况下,在服务器启动的时候会新建对象。
-
Servlet是单例的,Filter也是单例的。
-
-
目标Servlet是否执行,取决于两个条件:
-
第一:在过滤器当中是否编写了:chain.doFilter(request,response);代码。
-
第二:用户发送的请求路径是否和Servlet的请求路径一致。
-
-
chain.doFilter(request,response);这行代码的作用:
-
执行下一个过滤器,如果下面没有过滤器了,执行最终的Servlet。
-
-
注意:Filter的优先级,天生的就比Servlet高。
-
/a.do对应一个Filter,也对应一个Servlet。那么一定是先执行Filter,然后再执行Servlet。
-
-
关于Filter的配置路径:
-
/a.do、/b.do、/dept/save。这些配置方式都是精确匹配。
-
/* 匹配所有路径。
-
*.do 后缀匹配。(不要以 / 开始)
-
/dept/* 前缀匹配。
-
-
在web.xml文件中进行配置的时候,Filter的执行顺序:
-
依靠filter-mapping标签的匹配位置,越靠上优先级越高。
-
-
过滤器的调用顺序,遵循栈数据结构(先进后出,后进先出)。
-
使用@WebFilter的时候,Filter的执行顺序是怎么样的?
-
执行顺序是:比较Filter这个类名。
-
比如:
-
FilterA和FilterB,则先执行FilterA。
-
Filter1和Filter2,则先执行Filter1。
-
-
-
Filter的生命周期?
-
和Servlet对象的生命周期一致。
-
唯一的区别:Filter默认情况下,在服务器启动阶段就实例化,Servlet不会。
-
-
Filter过滤器这里有一个设计模式:
-
责任链设计模式。
-
过滤器最大的优点:
-
在程序编译阶段不会确定调用顺序。因为Filter的调用顺序是配置到web.xml文件中的,只要修改web.xml配置文件中filter-mapping的顺序就可以调整Filter的执行顺序。显然Filter的执行顺序是在程序运行阶段动态组合的。那么这种设计模式被称为责任链设计模式。
-
-
Listener监听器
-
什么是监听器?
-
监听器是Servlet规范中的一员。就像Filter一样。Filter也是Servlet规范中的一员。
-
在Servlet中,所有的监听器接口都是以"Listener"结尾。
-
-
监听器有什么用?
-
监听器实际上是Servlet规范留给我们JavaWeb程序员的特殊时机。
-
特殊的时刻如果想执行这段代码,就需要使用对应的监听器。
-
-
Servlet规范中提供了哪些监听器?
-
jakar.servlet包下:
-
ServletContextListener
-
ServletContextAttributeListener
-
ServletRequestListener
-
ServletRequestAttributeListener
-
-
jakarta.servlet.http包下:
-
HttpSessionListener
-
HttpSessionAttributeListener
-
该监听器需要使用@WebListener注解进行标注。
-
该监听器监听的是什么?是session域中数据的变化。只要数据变化,则执行相应的方法。主要检测点在session域对象上。
-
-
HttpSessionBindingListener
-
该监听器不需要使用@WebListener进行标注
-
假设User类实现了该监听器,那么User对象在被放入session的时候触发bind事件,User对象从session中删除的时候,触发unbind事件。
-
假设Customer类没有实现该监听器,那么Customer对象放入session或者从session删除的时候,不会触发bind和unbind事件。
-
-
HttpSessionIdListener
-
session的id发生改变的时候,监听器中的唯一一个方法就会被调用。
-
-
HttpSessionActivationListener
-
监听session对象的钝化和活化的。
-
钝化:session对象从内存存储到硬盘文件。
-
活化:从硬盘文件把session恢复到内存。
-
-
-
-
实现一个监听器的步骤:以ServletContextListener为例。
-
第一步:编写一个类实现ServletContextListener接口。并且实现里面的方法。
void contextInitialized(ServletContextEvent event) void contextDestroyed(ServletContextEvent event)
-
第二步:在web.xml文件中对ServletContextListener进行配置:
<listener> <listener-class>文件路径</listener-class> </listener>
当然,第二步也可以不适用配置文件,可以直接用注解: @WebListener
-
-
注意:所有监听器中的方法都是不需要javaweb程序员调用的,由服务器来负责调用,什么时候调用呢?
-
当某个特殊的事件发生(特殊的事件发生其实就是某个时机到了)之后,被web服务器自动调用。
-
- 点赞
- 收藏
- 关注作者
评论(0)