第八次学习任务

Servlet
重定向

重定向作用在客户端,客户端将请求发送给服务端后,服务器响应给客户端一个新的请求地址,客户端重新发送新请求。

页面跳转

在调用业务逻辑的Servlet中,编写一下代码

  • response.sendRedirect(“目标URL”);(不建议使用)

数据传输

sendRedirect跳转时,地址栏改变,代表客户端重新发送的请求,属于二次请求

  • response没有作用域,两次response请求中的数据无法共享
  • 传递数据:通过URL的拼接进行数据传递(“/webProject/b?username=tom”);
  • 获取数据:request.getParameter(“username”);

重定向特点

  • 重定向是客户端行为
  • 重定向是浏览器做了至少两次的访问请求
  • 重定向浏览器地址改变
  • 重定向两次跳转之间传输的信息会丢失(request范围)
  • 重定向可以指向任何的资源,包括当前应用程序中的其他资源,同一个站点上的其他应用程序中的资源,其他站点的资源。

Servlet生命周期四个阶段
实体化

当用户第一次访问Servlet时,由容器调用Servlet的构造器创建具体的Servlet对象,也可以在容器启动之后立刻创建实例,使用如下代码可以设置Servlet是否在服务器启动时就创建。
(load-on-startup)1(/load-on-startup)

  • 注意:只执行一次

初始化

在初始化阶段,init()方法会被调用。这个方法在javax.servlet.Servlet接口中定义。其中,方法以一个ServletConfig类型的对象作为参数。

  • 注意:init()方法只被执行一次

服务

当客户端有一个请求时,容器就会将请求ServletRequest与响应ServletResponse对象转给Servlet,以参数的形式传给Servlet方法。

  • 此方法会执行多次

销毁

当Servlet容器停止或者重新启动都会引起销毁Servlet对象并调用destroy方法。

  • destroy方法执行一次

Servlet特性
线程安全问题

Servlet在访问之后,会执行实例化操作,创建一个Servlet对象,而我们Tomcat容器可以同时多线程并发访问同一个Servlet,如果在方法中对成员变量做修改操作,就会有线程安全问题。

保证线程安全

  • synchronized
    将存在线程安全问题的代码放到同步代码块中
  • 实现SingleThreadMode接口
    Servlet实现SingleThreadMode接口后,每个线程都会创建Servlet实例,这样每个客户端请求就不存在共享资源问题,但是Servlet响应客户端请求的效率太低,所以已经淘汰。
  • 尽可能使用局部变量

状态管理
现有问题

  • HTTP协议量无状态的,不能保存每次提交的信息
  • 如果用户发来一个新的请求,服务器无法知道他是否与上次的请求有联系。
  • 对于那些需要多次提交数据才能完成的web操作,比如登录来说,就成问题了。

概念

将浏览器与web服务器之间多次交互当作一个整体来处理,并且将多次交互所涉及的数据(即状态)保存下来。

状态管理分类

  • 客户端状态管理技术:将状态保存在客户端,代表性的是Cookie技术。
  • 服务器状态管理技术:将状态保存在服务器端。代表性分是session技术(服务器传递session是需要使用Cookie方式和application)

Cookie的使用
什么是Cookie

  • Cookie是在浏览器访问服务端的某个资源时,由Web服务器在HTTP响应消息头中附带传送给浏览器的一小段数据。
  • 一旦web浏览器保存了某个Cookie,那么他在以后每次访问该web服务器时,都应在HTTP请求头中将这个Cookie回传给Web服务器。
  • 一个Cookie主要由标识该信息的名称(name)和值(value)组成。

获取Cookie

Cookie cookie = new Cookie("username","aaron");

cookie.setPath("/WebProject_war_exploded/get");

cookie.setMaxAge(60*60*24*7);

resp.addCookie(cookie);

修改Cookie

只要保证cookie的名称和路径一致即可改变

Cookie cookie = new Cookie("username","Gavin");

cookie.setPath("/WebProject_war_exploded/get");

cookie.setMaxAge(60*60);

resp.addCookie(cookie);

Cookie编码与解码

Cookie默认不支持中文,只能包含ASCLL字符,所以Cookie需要对Unicode字符进行编码,否则会出现乱码。

  • 编码可以使用java.net.URLEncoder类的encode(String str,String encoding)方法
  • 解码使用java.net.URLDecoder类的decode(String str,String encoding)方法

创建带中文Cookie

Cookie cookie = new Cookie(URLEncoder.encode("姓名","UTF-8"),URLEncoder.encode("张三","UTF-8"));

        cookie.setPath("/WebProject_war_exploded/get");

        cookie.setMaxAge(600);

        resp.addCookie(cookie);
for (Cookie cookie: cookies) {
    	     System.out.println(URLDecoder.decode(cookie.getName(),"UTF-8") +":"+URLDecoder.decode(cookie.getValue(),"UTF-8"));
            }

Cookie优点和缺点

优点

  1. 可配置到期规则
  2. 简单性:Cookie是一种基于文本的轻量结构,包含简单的键值对。
  3. 数据持久性:Cookie默认在过期之前是可以一直存在客户端浏览器上的。

缺点

  1. 大小受到限制:大多数浏览器对Cookie的大小有4k,8k字节的限制。
  2. 用户配置为禁用:有些用户禁用了浏览器或客户端设备接收Cookie的能力,因此限制了这一项功能。
  3. 潜在的安全风险:Cookie可能会被篡改,会对安全性造成潜在风险或者导致依赖于Cookie的应用程序失败。

Session
session概述

  • Session用于记录用户的状态,Session指的是在一段时间内,单个客户端与web服务器的一连串相关的交互过程。
  • 在一个Session中,客户可能会多次请求访问同一个资源,也有可能请求访问不同的服务器资源。

Session原理

服务器会为每一次话分配一个Session对象

  • 同一个浏览器发起的多次请求,同属于一次会话(session)
  • 首先使用到Session时,服务器会自动创建Session,开创建Cookie存储SessionId发送回客户端
    注意:Session是由服务端创建的。

Session使用

  • Session作用域:拥有存储数据的空间。作用范围是一次会话有效
  • 一次会话是使用同一浏览器发送的多次请求,一旦浏览器关闭,则结束会话
  • 可以将数据存入Session中,在一次会话的任意位置进行获取
  • 可传递任何数据(基本类型,对象,集合数组)

获取Session

//1.通过request对象获取Session对象
HttpSession session = request.getSession();

System.out.println(session.getId());

Session保存数据

setAttribute(属性名,Object)保存到Session中

session.setAttribute("username","gavin");

Session获取数据

getAttribute(属性名);获取session中数据

session.getAttribute("username");

Session移除数据

removeAttribute(属性名);从session中删除数据

session.removeAttribute("username");

Session和Request应用区别

  • request是一次请求有效,请求改变,则request改变
  • Session是一次会话有效,浏览器改变,则Session改变。

Session的生命周期

  • 开始:第一次使用则Session的请求产生,则创建Session
  • 结束:
    —浏览器关闭,则失效
    —Session超时,则失效
    ——session.getMaxInactiveInterval();//设置最大有效时间(单位为毫秒)
    —手工销毁,则失效
    ——session.invalidate();//立即失效
ServletContext对象

ServletContext概述

  • 全局对象,也拥有作用域,对应一个Tomcat中的web应用
  • 当web服务器启动时,会为每一个web应用程序创建一块共享的存储区域(ServletContext)。
  • ServletContext在web服务器启动时创建,服务器关闭时销毁。

获取ServletContext对象

  • GenericServlet提供了getServletContext()方法。(推荐)this.getServletContext();
  • HttpServletRequest提供了getServletContext()方法。(推荐)
  • HTTPSession提供了getServletCon()方法。
ServletContext作用

获取项目真实路径

获取当前项目在服务器发布的真实路径

获取项目上下文路径

获取项目上下文路径(应用程序名称)

全局容器

ServletContext拥有作用域,可以存储数据到全局容器中

  • 存储数据: servletContext.setAttribute(“name”,value);
  • 获取数据:servletContext.getAttribute(“name”);
  • 移除数据:servletContext.removeAttribute(“name”);

ServletContext特点

  • 唯一性:一个应用对应一个ServletContext。
  • 生命周期:只要容器不关闭或者应用不卸载,ServletContext就一直存在。

作用域总结

  • HttpServletRequest:一次请求,请求响应之前有效(临时数据的传递使用)
  • HttpSession:一次会话开始,浏览器不关闭或不超时之前有效(保存登录状态,权限验证使用)
  • ServletContext:服务器启动开始,服务器停止之前有效(全局容器状态:如计数器使用)
过滤器

现有问题

在以往Servlet中,有没有冗余的代码,多个Servlet都要进行编写。

概念

过滤器(Filter)是处于客户端与服务器目标资源之间的一道过滤技术。

过滤器
过滤器作用

  • 执行地位在Servlet之前,客户端发送请求时,会经过Filter,再到达目标Servlet中;响应时,会根据执行流程再次反向执行filter
  • 可以解决多个Servlet共性代码的冗余问题(例如:乱码处理,登录验证)

编写过滤器

Servlet API中提供了一个filter接口,开发人员编写一个Java类实现了这个接口即可,这个Java类称之为过滤器(filter)

实现过程

  • 编写Java类实现Filter接口
  • 在doFilter方法中编写拦截逻辑
  • 设置拦截路径

注解配置

在自定义的Filter类上使用注解@WebFilter(value = “/过滤目标资源”)

过滤器链和优先级

过滤器链

客户端对服务器请求之后,服务器调用Servlet之前会执行一组过滤器(多个过滤器),那么这组过滤器就称为一条过滤器链。

每个过滤器实现某个特定的功能,当第一个Filter的doFilter方法被调用时,Web服务器会创建一个代表Filter链的FilterChain对象传递给该方法,在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则Web服务器会检查FilterChain对象中是否还有Filter,如果有,则调用第2个Filter,如果没有,则调用目标资源。

在这里插入图片描述
过滤器优先级

在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。
优先级

  • 如果为注解的话,是按照类全名称的字符串顺序决定作用顺序
  • 如果web.xml,按照Filter.mapping注册顺序,从上往下
  • web.xml配置高于注解方式
  • 如果注解和web.xml同时配置,会创建多个过滤器对象,造成过滤多次。
过滤器典型应用

过滤器解决编码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值