javaweb3

举报
京与旧铺 发表于 2022/06/29 20:04:26 2022/06/29
【摘要】 关于转发跳转转发(一次请求)//第一步:获取请求转发器对象RequestDispatcher dispatcher = request.getRequesDispatcher("/b");//第二步:调用转发器的forward方法完成跳转/转发dispatcher.forward(request,response);​//第一步和第二步联合:request.getRequestDispatc...

关于转发

  1. 跳转

    • 转发(一次请求)

      • //第一步:获取请求转发器对象
        RequestDispatcher dispatcher = request.getRequesDispatcher("/b");
        //第二步:调用转发器的forward方法完成跳转/转发
        dispatcher.forward(request,response);
        ​
        //第一步和第二步联合:
        request.getRequestDispatcher("路径").forward(request,response);
  2. 两个Servle怎么共享数据?

    • 将数据放到request域当中,然后AServlet转发到BServlet,保证AServlet和BServlet在同一次请求中,这样就可以做到两个Servlet,或者多个Servlet共享同一份数据。

  3. 转发的下一个资源必须是一个Servlet吗?

    • 不一定,只要是Tomcat服务器当中的合法资源,都是可以转发的。例如:html...

    • 注意:转发的时候,路径的写法要注意,转发的路径以 "/" 开始,不加项目名。

  4. 关于request对象中两个非常容易混淆的方法:

    • //通过key获取value(获取请求域的值)
      String username = request.getParameter("username");
      ​
      //之前一定是执行过:request.setAttribute("name",new Object());
      //从request域中根据name获取数据
      Object obj = request.getAttribute("name");
      ​
      //以上两个方法的区别是什么?
      //第一个方法:获取的是用户在浏览器上提交的数据。
      //第二个方法:获取的是请求域当中绑定的数据。
  5. 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应用中应该如何完成资源的跳转

  1. 在一个web应用中通过两种方式,可以完成资源的跳转:

    • 第一种:转发

    • 第二种:重定向

  2. 转发和重定向有什么区别?

    • 代码上有什么区别?

      • 转发

        • //获取请求转发器对象
          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");
    • 形式上有什么区别?

    • 转发和重定向的本质区别?

      • 转发:是由WEB服务器来控制的。A资源跳转到B资源,这个跳转动作是Tomcat服务器内部完成的。

      • 重定向:是浏览器完成的。具体跳转哪个资源,是浏览器说了算。

  3. 转发和重定向应该如何选择?什么时候使用转发,什么时候使用重定向?

    • 如果上一个Servlet当中向request域当中绑定了数据,希望下一个Servlet当中把request域里面的数据取出来,使用转发机制。

    • 剩下的所有请求均使用重定向。(使用较多)


使用注解

  1. 在Servlet类上使用:@WebServlet

  2. @WebServlet注解中有哪些属性呢?

    • name属性:用来指定Servlet的名字。等同于:<servlet-name>

    • urlPatterns属性:用来指定Servlet的映射路径。可以指定多个字符串。<url-pattern>

    • loadOnStartUp属性:用来指定在服务器启动阶段是否加载该Servlet。等同于:<load-on-startup>

    • value属性:这个value属性和urlPatterns属性一致,都是用来指定Servlet的映射路径的。

    • 注意:

      • 不是必须将所有属性写上,只需提供需要的。

      • 当注解的属性是一个数组,并且数组中只有一个元素,花括号可以省略

      • 如果注解的属性名是value的话,属性名也可以省略

  3. 注解对象的使用格式:

    • @注解名称(属性名=属性值,属性名=属性值,....)


JSP

  1. 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都是假单例的。

  2. JSP是什么?

    • JSP是Java程序。(JSP本质还是一个Servlet)

    • JSP是:JavaServlet Pages的缩写。(基于Java语言实现的服务器端的页面)

    • Servlet是JavaEE的13个子规范之一,那么JSP也是JavaEE的13个子规范之一。

    • JSP是一套规范。所有的web容器/web服务器都是遵循这套规范的,都是按照这套规范进行的 “翻译”

  3. 在jsp中指定编码格式:

    //表示响应的内容类型是text/html,采用的字符集是utf-8。
    <%@page contentType="text/html;charset=UTF-8" %>
  4. 在jsp中编写Java程序

    <% Java语句; %>  //写在方法区中的Java代码
        
    <%! %>  //写在类体中的Java代码(很少用,存在线程安全问题)
    • 这个符号当中编写的被视为Java程序,被翻译到Servlet类的service方法内部。

    • 要注意编写方法的规范。(和Java中编写方法一致)

    • 在service方法当中编写的代码是有顺序的,方法体当中的代码要遵循自上而下的顺序逐行执行。

    • 在同一个jsp中,<%%>可以出现多个。

  5. JSP的专业注释

    <%-- JSP的专业注释,不会被翻译到Java源代码当中。 --%>
  6. JSP的输出语句

    //向浏览器输出一个Java变量
    <% String name = "tzw"; out.write("name =" + name);%>
    //注意:以上代码中的out是JSP的九大内置对象之一。只能在service方法的内部使用。
    ​
    <%= %> //这个符号代表的是-->out.print();在方法体里输出
    ​
    //注意:<% %>里面不能再添加<% %>
  7. 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异常。

  8. JSP本质上是一个Servlet,那么JSP和Servlet的区别是什么?

    • 职责不同

      • servlet的职责:收集数据。(Servlet的强项是逻辑处理,业务处理,然后连接数据库,获取 / 收集数据)

      • JSP的职责:展示数据。(JSP的强项是做数据的展示)

  9. 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


  10. 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机制)

  1. 什么是会话(session)?

    • 用户打开浏览器,进行一系列操作,然后最终将浏览器关闭,这个过程叫做:一次会话。

    • 会话在服务器端也有一个对应的Java对象,叫做:session。

    • 一个会话当中包含多次请求。

    • 在Java的servlet规范中,session对应的类名是:HttpSession(jakarta.servlet.http.HttpSession)

    • session机制实际上是一个规范,不同的语言对这种会话机制都有实现。

    • session对象最主要的作用是:保存会话状态。

  2. 为什么需要session对象来保存会话状态?

    • 因为HTTP协议是一种无状态协议。

    • 什么是无状态?

      • 请求的时候,B和S是连接的,但是请求结束后,连接就断了。

      • 为什么要这样做?因为这样的无状态协议,可以降低服务器压力。

      • 只要B和S断开了,那么关闭浏览器这个动作,服务器是不知道的。

  3. 为什么不使用request对象保存会话状态?为什么不使用ServletContext对象保存会话状态?

    • request.setAttribute()存,request.getAttribute()取,ServletContext也有这个方法。request是请求域,ServletContext是应用域。

    • request是一次请求一个对象。

    • ServletContext对象是服务器启动的时候创建,服务器关闭的时候销毁,这个ServletContext对象只有一个。(域太大)

    • request请求域(HttpServletRequest)、session会话域(HttpSession)、application域(ServletContext)

    • request < session < application

    • 他们三个域的公共方法:

      • setAttribute(向域中绑定数据)

      • getAttribute(从域当中获取数据)

      • removeAttribute(移除域当中的数据)

    • 使用原则:尽量使用小的域。

  4. session对象的实现原理

    • HttpSession session = request.getSession();

    • 张三访问的时候获取的session对象就是张三的,李四访问的时候获取的session对象就是李四的。

  5. session怎么获取?

    //从服务器上获取当前的session对象,如果没有则新建
    HttpSession session = request.getSession();
    
    //从服务器上获取当前对象,如果获取不到则不会新建,返回null(相当于禁用session)
    HttpSession session = request.getSession(false);
  6. session实现原理

    • JSESSIONID=xxxxx 这是以Cookie的形式保存在浏览器的内存中的。浏览器只要关闭,这个Cookle就没有了。

    • session列表是一个Map,map的key是sessionid,map的value是session对象。

    • 用户第一次请求,服务器生成session对象,同时生成id,将id发送给浏览器。

    • 用户第二次请求,自动将浏览器内存中的id发送给服务器,服务器根据id查找session对象。

    • 关闭浏览器,内存消失,cookie消失,sessionid消失,会话等同于结束。

  7. 为什么关闭浏览器,会话结束?

    • 关闭浏览器之后,浏览器中保存的sessionId消失,下次重新打开浏览器之后,浏览器缓存中没有这个sessionId,自然找不到服务器中对应的session对象,session对象找不到等同于会话结束。

  8. session什么时候被销毁?

    • 一种销毁:是超时销毁

    • 一种销毁:是手动销毁

      • session.invalidate();

  9. Cookie禁用了,session还能找到吗?

    • cookie禁用是什么意思?服务器正常发送cookie给浏览器,但是浏览器不要了,拒收了,并不是服务器不发了。

    • 找不到了,每一次请求都会获取到新的session对象。

    • cookie禁用了,session机制还能实现吗?

      • 可以,需要使用URL重写机制。(在地址后面添加;jsessionid=12D1212)

      • URL重写机制会提高开发者的成本。开发人员在编写任何请求路径的时候,后面都要添加一个sessionid,给开发带来了很大的难度,很大的成本。所以大部分网站禁用了cookie,就不能用了。


Cookie

  1. session的实现原理中,每一个session对象都会关联一个sessionid,例如:

    • JSESSIONID=B1B9FBE8076BE4E01F414A8BE8056119

    • 以上这个键值对数据就是cookie对象。

    • 对于session关联的cookie来说,这个cookie是被保存在浏览器的 “运行内存” 当中。只要浏览器不关闭,用户再次发送请求的时候,会自动将运行内存中的cookie发送给服务器,例如,这个cookie:JSESSIONID=B1B9FBE8076BE4E01F414A8BE8056119就会再次发送给服务器。服务器就是根据这个值来找对应的session对象的。

  2. cookie保存在什么地方?浏览器什么时候发送cookie,发送哪些cookie给服务器?

    • cookie最终是保存在浏览器客户端上的。

      • 可以保存在运行内存中(浏览器只要关闭cookie就消失了)

      • 也可以保存在硬盘文件中(永久保存)

    • 当第一次request的时候,服务器接收并创建cookie;用户第二次request的时候,浏览器发送请求并携带cookie一起发送给服务器。

    • 一个url对应一个cookie。(一对多)

  3. cookie有什么用?

    • cookie和session机制都是为了保存会话状态

    • cookie是将会话状态保存在浏览器客户端上

    • session是将会话状态保存在服务器端上。(session对象是存储在服务器上)

  4. 为什么要有cookie和session机制呢?

    • 因为http协议是无状态、无连接协议

  5. cookie机制和session机制都不属于Java机制,实际上cookie机制和session机制都是HTTP协议的一部分。PHP开发中也有cookie和session机制,只要是做web开发,cookie和session机制都是需要的。

  6. HTTP协议中规定:任何一个cookie都是由name和value组成的。name和value都是字符串类型的。

  7. 在Java的servlet中,提供了一个Cookie类来专门表示cookie数据。jakar.servlet.http.Cookie;

  8. java程序怎么把cookie数据发送给浏览器?response.addCookie(cookie);

  9. 在HTTP协议中是这样规定的:当浏览器发送请求的时候,会自动携带该path下的cookie数据给服务器。

  10. 关于cookie的有效时间

  • 怎么用Java设置cookie的有效时间?

    • cookie.setMaxAge(60*60);//设置cookie在一小时之后失效
      ​
      //如果设置有效时间为0,则表示cookie被删除。主要应用在删除浏览器上的同名cookie
      ​
      //设置cookie的有效时间 <0 ,表示该cookie不会被存储。(表示不会被存储在硬盘文件中,会放在浏览器运行内存当中。和不调用setMaxAge是同一效果)
  • 没有设置有效时间:默认保存在浏览器运行内存中,浏览器关闭则cookie消失。

  • 只要设置cookie的有效时间>0,这个cookie一定会存储到硬盘文件当中。

  1. 设置cookie的关联路径方法:cookie.setPath(“路径名”);

  2. 关于cookie的path,cookie关联的路径:

  3. 手动设置cookie的path

    cookie.setPath("/servlet"); //表示只要是这个servlet项目的请求路径,都会提交这个cookie给服务器。
  4. 浏览器发送cookie给服务器了,服务器中的Java程序怎么接收?

    Cookie[] cookies = request.getCookies(); //这个方法可能返回null
    if(cookies != null){
        for(Cookie cookie : cookies){
            String name = cookie.getName();
            String name = cookie.getValue();
        }
    }

EL表达式

  1. EL表达式

    • Expression Language(表达式语言)

    • EL表达式可以代替JSP中的Java代码,让JSP文件中的程序看起来更加整洁、美观

    • EL表达式归属于JSP

    • EL表达式只能取,不能存。

  2. EL表达式在JSP中的主要作用:

    • 从某个域中取出数据

    • 将取出的数据转换成字符串

    • 将字符串输出到浏览器

  3. EL表达式基本的语法格式:

    • ${表达式}

  4. 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集合没有下标。
  5. 忽略EL表达式:

    • <%@page isELIgnored="true" %> //这是全局控制

    • 如果是false,则表示不忽略EL表达式(默认值)

    • 可以使用反斜杠进行局部控制:

      \${username} 这样也可以忽略EL表达式
  6. 使用EL表达式获取应用的根路径

    • ${pageContext.request.contextPath}

  7. EL表达式的常用隐式对象:

    • pageContext

      应用的根路径:${pageContext.request.contextPath}
    • param

      爱好:${param.aihao} //获取的是请求参数一维数组当中的第一个元素
    • paramValues

      爱好:${paramValues.aihao[0],paramValues.aihao[1],paramValues.aihao[2]} 
      //获取数组中的元素
    • initParam

  8. EL运算符:

    • 在EL表达式中,"+"运算符只能做求和运算,不会进行字符串拼接操作。当两边不是数字的时候,一定会转换成数字,转不成数组就报错。NumberFormatException。

    • EL表达式当中的 "==" 调用了重写的equals方法。(EL中还有一个运算符 eq ,和这个一样)

    • ${empty param.username} 判断是否为空


JSTL标签库

  1. 什么式JSTL标签库?

    • Java Standard Tag Lib(Java标准的标签库)

    • JSTL标签库通常结合EL表达式一起使用,目的式让JSP中的Java代码消失。

    • 标签是写在JSP中的,但实际上最终还是要执行对应的Java程序。(Java程序在jar包中)

  2. JSTL的核心标签库

    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  3. 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文件。
  4. 配置文件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过滤器

  1. Filter是什么,有什么用,执行原理是什么?

    • Filter是过滤器

    • Fiter可以写在Servlet这个目标程序执行之前添加代码。也可以在目标Servlet执之后添加代码。之前之后都可以添加过滤规则。

    • 一般情况下,都是在过滤器当中编写公共代码。

  2. 过滤器的写法:

    • 第一步:编写一个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"})   //不推荐使用注解,因为后续更改过滤器执行顺序不方便,会修改源代码
  3. 注意:

    • Servlet对象默认情况下,在服务器启动的时候是不会新建对象的。

    • Filter对象默认情况下,在服务器启动的时候会新建对象。

    • Servlet是单例的,Filter也是单例的。

  4. 目标Servlet是否执行,取决于两个条件:

    • 第一:在过滤器当中是否编写了:chain.doFilter(request,response);代码。

    • 第二:用户发送的请求路径是否和Servlet的请求路径一致。

  5. chain.doFilter(request,response);这行代码的作用:

    • 执行下一个过滤器,如果下面没有过滤器了,执行最终的Servlet。

  6. 注意:Filter的优先级,天生的就比Servlet高。

    • /a.do对应一个Filter,也对应一个Servlet。那么一定是先执行Filter,然后再执行Servlet。

  7. 关于Filter的配置路径:

    • /a.do、/b.do、/dept/save。这些配置方式都是精确匹配。

    • /* 匹配所有路径。

    • *.do 后缀匹配。(不要以 / 开始)

    • /dept/* 前缀匹配。

  8. 在web.xml文件中进行配置的时候,Filter的执行顺序:

    • 依靠filter-mapping标签的匹配位置,越靠上优先级越高。

  9. 过滤器的调用顺序,遵循栈数据结构(先进后出,后进先出)。

  10. 使用@WebFilter的时候,Filter的执行顺序是怎么样的?

    • 执行顺序是:比较Filter这个类名。

    • 比如:

      • FilterA和FilterB,则先执行FilterA。

      • Filter1和Filter2,则先执行Filter1。

  11. Filter的生命周期?

    • 和Servlet对象的生命周期一致。

    • 唯一的区别:Filter默认情况下,在服务器启动阶段就实例化,Servlet不会。

  12. Filter过滤器这里有一个设计模式:

    • 责任链设计模式。

    • 过滤器最大的优点:

      • 在程序编译阶段不会确定调用顺序。因为Filter的调用顺序是配置到web.xml文件中的,只要修改web.xml配置文件中filter-mapping的顺序就可以调整Filter的执行顺序。显然Filter的执行顺序是在程序运行阶段动态组合的。那么这种设计模式被称为责任链设计模式。


Listener监听器

  1. 什么是监听器?

    • 监听器是Servlet规范中的一员。就像Filter一样。Filter也是Servlet规范中的一员。

    • 在Servlet中,所有的监听器接口都是以"Listener"结尾。

  2. 监听器有什么用?

    • 监听器实际上是Servlet规范留给我们JavaWeb程序员的特殊时机。

    • 特殊的时刻如果想执行这段代码,就需要使用对应的监听器。

  3. 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恢复到内存。

  4. 实现一个监听器的步骤:以ServletContextListener为例。

    • 第一步:编写一个类实现ServletContextListener接口。并且实现里面的方法。

      void contextInitialized(ServletContextEvent event)
      void contextDestroyed(ServletContextEvent event)
    • 第二步:在web.xml文件中对ServletContextListener进行配置:

      <listener>
          <listener-class>文件路径</listener-class>
      </listener>
      当然,第二步也可以不适用配置文件,可以直接用注解:
          @WebListener
  5. 注意:所有监听器中的方法都是不需要javaweb程序员调用的,由服务器来负责调用,什么时候调用呢?

    • 当某个特殊的事件发生(特殊的事件发生其实就是某个时机到了)之后,被web服务器自动调用。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。