客户端与服务端会话技术

会话技术

  1. 会话:一次会话中包含多次请求
    • 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止
  2. 功能:在一次绘画的范围内的多次请求间,共享数据
  3. 方式:
    1. 客户端会话技术:Cookie
    2. 服务端会画技术:Session

1.Cookie

概念:客户端会话技术,将数据保存到客户端

快速入门:

  • 使用步骤:
    1. 创建cookie对象,绑定数据
      • new Cookie(String name , String value)
    2. 发送cookie对象
      • response.addCookie(Cookie cookie)
    3. 获取Cookie,拿到数据
      • Cooke[] request.getCookies()

实现原理

  • 基于响应头set-cookie和请求头cookie实现

cookie的细节

  1. 一次可不可以发送多个cookie?

    • 可以创建多个Cookie对象,使用response调用多次addCookie方法发送cookie即可

        //1.创建CooKie对象
              Cookie c1=new Cookie("msg","hello");
              Cookie c2=new Cookie("msg","hello");
              //2.发送Cookie
              response.addCookie(c1);
              response.addCookie(c2);
      
  2. cookie在浏览器中保存多长时间?

    1. 默认情况下,当浏览器关闭后,Cookie数据被销毁

    2. 持久化存储:

      • setMaxAge(int seconds)

        //设置cookie的存活时间
                c1.setMaxAge(30);//将cookie持久化到硬盘,30秒后会自动删除cookie文件
        
        1. 正数:将Cookie数据写到硬盘的文件中,持久化存储。cookie存活时间。
        2. 负数:默认值。
        3. 零:删除cookie信息
    3. cooklie能不能存中文?

      • 在tomcat8之前 cookie中不能直接存储中文数据
        需要将中文数据编码–一般采用URL编码(%E3)
      • 在tomcat8之后,cookie支持中文数据
    4. cookie获取范围多大?

      • 假设在一个tomact服务器中,部署了多个web项目,那么在这些web项目中cookie能不能共享?
        • 默认情况下cookie不能共享
        • setPath(String path): 设置cookie的获取范围。
        • 如果要共享,则可以将Path设置为”/“
      • 不同的tomcat服务器间cookie共享问题?
        • setDomain(String path):如果设置一级域名相同,那么多个服务器之间cookie可以共享
          setDomain(“.baidu.com”),那么tieba.baidu.com和news.baidu.com中cookie可以共享
    5. Cookie的特点和作用

      1. Cookie存储数据在客户端浏览器
      2. 浏览器对于单个cookie 的大小有限制(4kb) 以及 对同一个域名下的总cookie数量也有限制(20)
      3. 作用:
        1. cookie一般用于存储少量的不太敏感的数据
        2. 在不登陆的情况下,完成服务器对客户端的身份识别
    6. 案例:记住上一次访问时间

      1. 需求:

        1. 访问一个servlet,如果是第一次访问,则提示:您好,欢迎您首次访问。
        2. 如果不是第一次访问,则提示:欢迎回来,您上次访问时间为:显示时间字符串
      2. 分析:

        1. 可以采用Cookie来完成

        2. 在服务器中的Servlet判断是否有一个名为lastTime的cookie

          1. 有:不是第一次访问
            1. 响应数据:欢迎回来,您上次访问时间为:上次访问时间
            2. 写回Cookie:lastTime=访问时间
          2. 没有:是第一次访问
            1. 响应数据:您好,欢迎您首次访问
            2. 写回Cookie:lastTime=访问时间
        3. 代码实现

             //设置响应的消息体的数据格式以及编码
                  response.setContentType("text/html;charset=utf-8");
                  
                  //1.获取所有Cookie
                  Cookie[] cookies = request.getCookies();
                  boolean flag = false;//没有cookie为lastTime
          
                  //2.遍历cookie数组
                  for (Cookie cookie : cookies) {
                      //3.获取cookie的名称
                      String name = cookie.getName();
                      //4.判断名称是否是:lastTime
                      if ("lastTime".equals(name)) {
                          //有Cookie,不是第一次访问
                          flag = true;//有lastTime的cookie
                          //设置cookie的value
                          //获取当年时间的字符串,重新设置cookie的值,重新发送cookie
                          Date date = new Date();
                          SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日  HH:mm:ss");
                          String str_date = sdf.format(date);
                          System.out.println("编码前:"+str_date);
                          //URL编码
                          str_date = URLEncoder.encode(str_date, "utf-8");
                          System.out.println("编码后:"+str_date);
                          cookie.setValue(str_date);
                          //设置cookie的存活时间
                          cookie.setMaxAge(60 * 60 * 24 * 30);//一个月
          
                          response.addCookie(cookie);
          
                          //响应数据
                          //获取cookie的value,时间
                          String value = cookie.getValue();
                          System.out.println("解码前:"+value);
                          //URL解码
                          value= URLDecoder.decode(value,"utf-8");
                          System.out.println("解码后:"+value);
                          response.getWriter().write("<h1>欢迎回来,您上次访问时间为:" + value + "</h1>");
          
                          break;
                      }
          
                  }
          

          这里使用URL编解码防止空格字符无法转化为cookic数据

           if (cookies == null || cookies.length == 0 ||flag==false){
                      //没有,第一次访问
                      //设置cookie的value
                      //获取当年时间的字符串,重新设置cookie的值,重新发送cookie
                      Date date = new Date();
                      SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日  HH:mm:ss");
                      String str_date = sdf.format(date);
                      str_date = URLEncoder.encode(str_date, "utf-8");
                      Cookie cookie=new Cookie("lastTime",str_date);
                      cookie.setValue(str_date);
                      //设置cookie的存活时间
                      cookie.setMaxAge(60 * 60 * 24 * 30);//一个月
                      response.addCookie(cookie);
                      response.getWriter().write("<h1>您好,欢迎您首次访问</h1>");
                  }
          

2.JSP:入门学习

2.1概念

  • Java Server Pages:java服务器端页面
    • 可以理解为:一个特殊的页面,其中既可以定义html的标签,又可以定义java代码
    • 用于简化书写

2.2原理

  • JSP本质上就是一个servlet

2.3JSP的脚本

(JSP定义java代码的方式)

  1. <% 代码 %>:定义的java代码,在service方法中,service方法中可以定义什么,该脚本就可以定义什么
  2. <%! 代码 %>:定义的java代码,在jsp转换后的java类的成员位置。(建议不要使用,容易引发线程安全问题)
  3. <%= 代码 %>:定义的java代码,会输出到页面上。

2.4JSP的内置对象

  • 在jsp页面中不需要获取和创建,可以直接使用的对象

  • jsp一共有9个对象

    1. pageContext

    2. request

    3. session

    4. application

    5. reponse

  1. page

  2. out:字符输出流对象。可以将数据输出到页面上。和response.getwrite()类似

- response.getwriter()和out.write()的区别
  
  - 在tomcat服务器真正给客户端做出响应之前,会先找response缓冲区数据,再找out缓冲区数据
  - response.getwriter()数据输出永远在out.write()之前
  1. config

  2. exception

    变量名真实类型作用
    pageContextPageContext当前页面共享数据,还可以获取其他8个内置对象
    requestHttpServletRequest一次请求访问的多个资源(转发)
    sessionHttpSession一次会话的多个请求间
    applicationServletContext所有用户间共享数据
    responseHttpServletResponse响应对象
    pageObject当前页面的(Servlet)对象 this
    outJspwriter输出对象,数据输出到页面上
    configServletConfigServlet的配置对象
    exceptionThrowable异常对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HlsTqzSG-1622027444539)(D:\Java\Java\03-Javaweb\day16_Cookie&Session\课件资料\课件资料\截图\JSP原理.bmp)]

2.5指令

  • 作用:用于配置jsp页面,导入资源文件

  • 格式:

    ​ <%@ 指令名称 属性名1=属性值1 属性名2=属性值2… %>

  • 分类:

    1. page :配置JSP页面的

      • contentType:等同于response.setContentType()
        1. 设置响应体的mime类型以及字符集
        2. 设置当前jsp页面的编码
          (只能是高级的IDE才能生效,如果使用低级工具,则需要pageEncoding属性设置当前页面的字符集)
      • import:导包
      • errorPage:当前页面发生异常后,会自动跳转
      • isErrorPage:标识当前页面是否是错误页面。
        • true:是,可以使用内置对象exception
        • false:否,默认值。不可以使用内置对象exception
    2. include :页面包含的。导入页面的资源文件

      • <%@include file="top.jsp"%>
        
    3. taglib : 导入资源

      • <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
        
      • prefix:前缀,自定义的

2.6注释

  1. html注释: :只能注释html代码片段,会发送到页面源码中
  2. jsp注释:
    <%-- --%>:可以注释所有,不会发送到页面源码中(推荐)

3.Session:主菜

  1. 概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端对象中。HttpSession

  2. 快速入门:

    1. 获取HttpSession对象:
      HttpSession session = request.getSession();

    2. 使用HttpSession对象:

      Object getAttribute(String name)
      void setAttribute(String name, Object value)
      void removeAttribute(String name)
      
  3. 原理

    • Session的实现是依赖于Cookie的。
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4cL8r4Kr-1622027444540)(D:\Java\Java\03-Javaweb\day16_Cookie&Session\课件资料\课件资料\截图\Session原理.bmp)]
  4. 细节:

    1. 当客户端关闭后,服务器不关闭,两次获取session是否为同一个?

      • 默认情况下不是

      • 如果需要相同,则可以创建cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存

         //期望客户端关闭后,session也能相同
                Cookie c=new Cookie("JSESSIONID",session.getId());
                c.setMaxAge(60*60);
                response.addCookie(c);
        
    2. 客户端不关闭,服务器关闭后,两次获取的session是同一个吗?

      • 不是同一个,但是要确保数据不丢失
    • session的钝化:
      - 在服务器正常关闭之前,将session对象系列化到硬盘上
      - session活化:
      - 在服务器启动后,将session文件转化为内存中的session对象即可。
    1. session的失效时间?

      1. 服务器关闭

      2. session对象调用invalidate().

      3. session 默认失效时间 30分钟

        选择配置修改

        <session-config>
        	<session-timeout>30</session-timeout>
        </session-config>
        
  5. session的特点

    1. session用以存储一次会话的多次请求的数据,存在服务器端
    2. session可以存储任意类型,任意大小的数据
    • session与Cookie的区别
      1. session存储数据在服务器端,cookie在客户端
      2. session没有数据大小限制,Cookie有
      3. session数据安全,Cookie相对不安全

案例:验证码

  1. 案例需求:
    1. 访问带有验证码的登陆界面login.jsp
    2. 用户输入用户名,密码以及验证码。
      • 如果用户名和密码输入有误,跳转到登陆界面,提示:用户名或密码错误
      • 如果验证码输入有误,跳转到登陆界面,提示:验证码错误
      • 如果全部输入正确,则跳转到主页success.jsp,显示:用户名,欢迎您
  2. 分析:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aT5Aln2X-1622027444541)(D:\Java\Java\03-Javaweb\day16_Cookie&Session\课件资料\课件资料\截图\登录案例.bmp)]

MVC开发模式

1.jsp演变历史

  1. 早期只有servlet,只能使用response输出标签数据,非常麻烦
  2. 后出现了jsp,简化了servlet的开发,如果过度使用jsp,在jsp中即写大量的java代码,有写html表
    难于维护,难于分工
  3. 之后出现了web开发,借鉴mvc开发模式,使得程序的设计更加合理

2.MVC

  1. M:Modle,模型
    • 完成具体的业务操作,如:查询数据库,封装对象
  2. V:View:视图
    • 展示数据
  3. C:Controller:控制器
    • 获取用户的输入(获取请求参数)
    • 调用模型
    • 将数据交给视图进行展示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FzGLSCHo-1622027444543)(D:\Java\Java\03-Javaweb\day17_EL&JSTL\课件资料\课件资料\截图\MVC开发模式.bmp)]

  • 优缺点:
    1. 优点:
      1. 耦合性低,方便维护,可以利于分工协作
      2. 重用性高
    2. 缺点:
      1. 使得项目架构变得复杂,对开发人员要求高

EL表达式

  1. 概念:Expression Language 表达式语言
  2. 作用:替换和简化jsp页面中java代码的编写
  3. 语法:$(表达式)
  4. 注意:
    • jsp默认支持el表达式的。如果要忽略el表达式
      1. 设置jsp中page指令中:isELIgnored=“true”忽略当前jsp页面中所有的el表达式
      2. $(表达式):忽略当前el表达式
  5. 使用:
    1. 运算:

      • 运算符:
        1. 算出运算符:+ - * / (div) % (mod)
        2. 比较运算符:> < >= <= == !=
        3. 逻辑运算符: &&(and) ||(or) !(not)
        4. 空运算符:empty
          • 功能:用于判断字符串、集合、数组对象是否为null并且长度是否为0
          • $(empty list)
          • $(not empty str):表示判断字符串、集合、数组对象是否不为null 并且 长度>0
    2. 获取值

      1. el表达式只能从域对象中获取值
      2. 语法:
        1. ${域名称.键名}:从指定域中获取指定键的值
          • 域名称:
            1. pageScope -->pageContext
            2. requstScope -->request
            3. sessionScope -->session
            4. applicationScope -->applocation(Servlet)
          • 举例:在request域中存储了name=张三
            获取:$(requestcope.name)
        2. ${键名}:表示依次从最小的域中查找是否有该键对应的值,直到找到为止。
      3. 获取对象、List集合、Map集合的值
        1. 对象:${域名称.键名.属性名}
          • 本质上会去调用对象的getter方法
        2. List集合:${域名称.键名.属性名}
        3. Map集合:
          • ${域名称.键名.Key名称}
          • ${域名称.键名[“Key名称”]}
    3. 隐式对象:

      • el表达式中有11个隐式对象

      • pageContext:

        • 获取jsp其他八个内置对象

          ${pageContext.request.contextPath}:动态获取虚拟目录

JSTL

  1. 概念:javaserver pages Tag Library JSP标准标签库
    是由Apache组织提供的开源的免费的jsp标签 <标签>

  2. 作用:用于简化和替换jsp页面上的java代码

  3. 使用步骤:

    1. 导入jstl相关jar包
    2. 引入标签库:taglib指令:<%@ taglib %>
    3. 使用标签
  4. 常用的JSTL标签

    1. if :相当于java代码的if语句

      1. 属性:
        • text 必须属性,接受boolean表达式
          • 如果表达式为true,则显示if标签体内容,如果为false,则不显示标签体内容
          • 一边情况下text属性值会结合el表达式一起使用
      2. 注意:
        • c:if标签没有else情况,想要else情况,可以再定义一个c:if标签
    2. choose :相当于java代码的switch语句

      1. 使用choose标签声明 相当于switch声明
      2. 使用when标签做判断 相当于case
      3. 使用otherwise标签做其他声明 相当于default
    3. foreach :相当于java代码的for语句

      1. 完成重复的操作
        for(int i=0;i<10 i++){}

        • 属性:
          begin:开始值
          end:结束值
          var:临时变量
          step:步长
          varStatus:循环状态对象
          index:容器中的索引,从0开始
          count:循环次数

        • <c:forEach begin="1" end="10" var="i" step="1">
          ${i}<br>
          </c:forEach>
          
        • <c:forEach begin="1" end="10" var="i" step="2" varStatus="s">
          ${i}<h3>${s.index}<h3> <h4>${s.count}<h4><br>
          </c:forEach>
          
      2. 遍历容器

        List<User user:list>{}
        for(User user:list){}
        
        • 属性:

          • items:容器对象
          • var:容器中元素的临时变量
          • varStatus:循环状态对象
            • index:容器中元素的索引,从0开始
            • count:循环次数,从1开始
        • <%
          List list=new ArrayList();
          list.add("aaa");
          list.add("bbb");
          list.add("ccc");
          request.setAttribute("list",list);
          %>
          <c:forEach item="${list}" var="str" varStatus="s">
          ${s.index} $(s.count) $(str)<br>
          </c:forEach>
          
  5. 练习

    • 需求:在request域中有一个存有User对象的List集合。
      需要使用jstl+el将list集合数据展示到jsp页面的表格table中

    • <%
          List list = new ArrayList();
          list.add(new User("张三",23,new Date()));
          list.add(new User("李四",24,new Date()));
          list.add(new User("王五",25,new Date()));
          request.setAttribute("list",list);
      %>
      <table border="1" width="500" align="center">
          <tr>
              <th>编号</th>
              <th>姓名</th>
              <th>年龄</th>
              <th>生日</th>
          </tr>
          <%--数据行--%>
          <c:forEach items="${list}" var="user" varStatus="s">
              <c:if test="${s.count % 2 != 0}">
                  <tr bgcolor="red">
                      <td>${s.count}</td>
                      <td>${user.name}</td>
                      <td>${user.age}</td>
                      <td>${user.bitStr}</td>
                  </tr>
              </c:if>
      
              <c:if test="${s.count % 2 == 0}">
      
                  <tr  bgcolor="green">
                      <td>${s.count}</td>
                      <td>${user.name}</td>
                      <td>${user.age}</td>
                      <td>${user.bitStr}</td>
      
                  </tr>
              </c:if>
          </c:forEach>
      </table>
      
    • 其中User对象直接调用类的属性或者方法名

三层架构:软件设计架构

  1. 三层架构:
    1. 页面层(表示层):用户看到的界面。用户可以通过界面上的组件和服务器进行交互
    2. 业务逻辑层:处理业务逻辑的。
    3. 数据访问层:操作数据存储文件。
  2. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yA6l9qQY-1622027444544)(D:\Java\Java\03-Javaweb\day17_EL&JSTL\课件资料\课件资料\截图\三层架构.bmp)]
  3. 案例:用户信息列表展示

Filter:过滤器

  1. 概念:

    • 生活中的过滤器:净水器,空气净化器
    • web中的过滤器:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能。
    • 过滤器的作用:
      • 一般用于完成通用的操作。如:登陆验证,统一验证码处理、敏感字符过滤…
  2. 快速入门

    1. 步骤:

      1. 定义一个类,实现接口Filter

      2. 复写方法

      3. 配置拦截路径

        1. web.xml

          <filter>
                  <filter-name>demo1</filter-name>
                  <filter-class>cn.itcast.Filter.filterDemo1</filter-class>
              </filter>
              <filter-mapping>
                  <filter-name>demo1</filter-name>
                  <url-pattern>/*</url-pattern>
              </filter-mapping>
          
        2. 注解

          @WebFilter("/*")//拦截所有访问资源
          
    2. 代码

      public class filterDemo1 implements Filter {
          @Override
          public void init(FilterConfig filterConfig) throws ServletException {
              System.out.println(123);
          }
      
          @Override
          public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
              System.out.println("filterDemo1被执行了");
              //放行
              filterChain.doFilter(servletRequest,servletResponse);
          }
          @Override
          public void destroy() {
              System.out.println(234);
          }
      }
      
  3. 过滤器细节:

    1. web.xml配置

      <filter>
              <filter-name>demo1</filter-name>
              <filter-class>cn.itcast.Filter.filterDemo1</filter-class>
          </filter>
          <filter-mapping>
              <filter-name>demo1</filter-name>
              <url-pattern>/*</url-pattern>
              <!-- 拦截路径-->
          </filter-mapping>
      
    2. 过滤器执行流程

      1. 执行过滤器
      2. 执行放行后的资源
      3. 回来执行过滤器放行代码下边的代码
    3. 过滤器生命周期方法

      1. init:在服务器启动后,会创建Filter对象,然后调用init方法。只执行依次。用于加载资源
      2. doFilter:每一次请求被拦截资源时,会执行。(多次执行)
      3. destroy:在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法。只执行一次,用于释放资源
    4. 过滤器配置详解

      • 拦截路径设置:
        • 注解配置:
          1. REQUEST:默认值。浏览器直接请求资源
          2. FORUARD:转发访问资源
          3. INCLUDE:包含访问资源
          4. ERROR:错误跳转资源
          5. ASYNC:异步访问资源
        • web.xml配置
          • 设置标签即可
    5. 过滤器链(配置多个过滤器)

      • 执行顺序:如果有两个过滤器:过滤器和过滤器2
        1. 过滤器1
        2. 过滤器2
        3. 资源执行
        4. 过滤器2
        5. 过滤器1
      • 过滤器先后顺序问题
        1. 注解配置:按照类名的字符串比较规则比较,值小的先执行
          • 如:AFilter和BFilter,AFilter就先执行
        2. web.xml配置:谁定义在上边,谁先执行
      • 增强对象的功能:
        • 设计模式:一些通用的解决固定问题的方式
          • 装饰模式
          • 代理模式
            • 概念
              1. 真实对象:被代理的对象
              2. 代理对象
              3. 代理模式:代理对象代理真实对象,达到增强真实对象功能的目的
            • 实现方式:
              1. 静态代理:有一个类文件描述代理模式
              2. 动态代理:在内存中形成代理类
            • 实现步骤:
              1. 代理对象和展示对象实现相同的接口
              2. 代理对象=Proxy.newProxyInstance
              3. 使用代理对象调用方法
              4. 增强方法
            • 增强方式:
              1. 增强参数列表
              2. 增强返回值类型
              3. 增强方法体执行逻辑

Listener:监听器

  • 概念:web的三大组件之一。

    • 事件监听机制
      • 事件:一件事情
      • 事件源:事件发生的地方
      • 监听器:一个对象
      • 注册监听:将事件,事件源,监听器绑定在一起。
        当事件源上发生某个时间后,执行监听器代码
  • ServletContextListener:监听ServletContext对象的创建和销毁

    • 方法:

      • void contextDestroyed(ServletContextEvent sce):ServletContext对象被销毁之前会调用该方法
      • void contextInitialialized(ServletContextEvent sce):ServletContext对象创建后会调用该方法
    • 步骤:

      1. 定义一个类,实现ServletContextListener接口

      2. 复写方法

      3. 配置

        1. web.xml

          <listener>
          <listener-class>cn.itcast.web.ContextLoaderListener</listener-class>
          </listener>
          
        2. 注解

          • @webListener

回值类型
3. 增强方法体执行逻辑

Listener:监听器

  • 概念:web的三大组件之一。

    • 事件监听机制
      • 事件:一件事情
      • 事件源:事件发生的地方
      • 监听器:一个对象
      • 注册监听:将事件,事件源,监听器绑定在一起。
        当事件源上发生某个时间后,执行监听器代码
  • ServletContextListener:监听ServletContext对象的创建和销毁

    • 方法:

      • void contextDestroyed(ServletContextEvent sce):ServletContext对象被销毁之前会调用该方法
      • void contextInitialialized(ServletContextEvent sce):ServletContext对象创建后会调用该方法
    • 步骤:

      1. 定义一个类,实现ServletContextListener接口

      2. 复写方法

      3. 配置

        1. web.xml

          <listener>
          <listener-class>cn.itcast.web.ContextLoaderListener</listener-class>
          </listener>
          
        2. 注解

          • @webListener
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值