session和过滤器

回顾

  1. 1.无查询分页,pageIndex,pageSize,pageMax,==>分页语句的算法
  2. 2.模糊查询分页
  3. a.刚进入页面应该就是一个模糊查询,“%%”
  4. b.查询条件的保存,分页插件传值时记得传查询条件
  5. 拓展:在传值时,出现类参数太多的问题?形参太多?放到request域中的值太多了?封装===》pageBean==>javaBean
  6. 3.http请求的无状态性
  7. 4.解决无状态性的方案:将状态保持在客户端(cookie),或者将状态保存在服务器(session)
  8. 5.cookie的工作原理:自动发送原则,cookie是根据url来匹配路径,自动发送
  9. 6.cookie的简单用法,怎么存?responseadd进去,怎么取?requset去取,有效时间:默认值-1
  10. 网络编程里面叫做URLEncoder这个类进行编码和URLDecoder进行解码
  11. 编码:URLEncoder.encode(中文,编码类型);
  12. 解码:URLDecoder.decode(中文,解码类型);
  1. 1.什么是session
  2. 2.session的工作原理
  3. 3.了解session超时
  4. 4.验证码登录
  5. 5.什么是过滤器
  6. 6.过滤器链===》shiro的核心知识点
  7. 7.过滤器的应用
  1. 1.熟悉什么是session
  2. 2.熟悉session的工作原理
  3. 3.了解session超时
  4. 4.验证码登录
  5. 5.掌握什么是过滤器
  6. 6.掌握过滤器链===》shiro的核心知识点
  7. 7.过滤器的应用

第一节 状态管理-Session

1.1 Session概述

1.1.1 什么是Session
  1. Session用于跟踪客户的状态。Session指的是在一段时间内,单个客户与Web服务器的一连串相关的交互过程。
  2. 在一个Session中,客户可能会多次请求访问同一个网页,也有可能请求访问各种不同的服务器资源。
  3. 表示的是会话,session域中存的值,他的有效范围是一次会话,浏览器代开访问服务器到访问结束关闭浏览器这段时间,这就是使用session去解决无状态性。session他的是属于服务器的

1.1.2 Session工作原理
  1. 1.当浏览器第一发送请求给服务器时,那么服务器会在内存中开辟一个对象(session),通过hash算法得到这个对象的内存地址(eac123456),此时服务器会new cookie对象(new Cookie("JsessionId","eac123456")),将cookie添加到response中响应给浏览器进行存储。
  2. 2.当同一个浏览器第二次访问同一台服务器,根据cookie的自动发送原则,会将匹配到url的cookie封装到request请求中,那么此时服务器回去解析cookie,拿到JsessionId所对应的内存地址eac123456,根据内存地址找到原来new的对象(session对象),将对象关联给request
  3. 3.第三次,第四次以此类推

1.1.3 如何获得Session
  1. //获取Session对象
  2. HttpSession session=request.getSession();
  3. System.out.println("Id:"+session.getId());//唯一标记,和jSessionId不一样
  4. System.out.println("getLastAccessedTime:"+session.getLastAccessedTime());//最后一次访问时间,毫秒
  5. System.out.println("getMaxInactiveInterval:"+session.getMaxInactiveInterval());//获取最大的空闲时间,单位秒
  6. System.out.println("getCreationTime:"+session.getCreationTime());//获取Session的创建,单位毫秒

1.1.4 如何使用Session绑定对象
  1. 使用HttpSessionsetAttribute(属性名,Object)方法

1.1.5 如何删除Session
  1. 使用HttpSessioninvalidate方法

注意:如何理解session的作用范围是一次会话
  1. 1.session有着自己的生命周期,可以自己设定时长
  2. 2.是因为存放原来JsessionId的那个cookiemaxAge=-1;浏览器关闭了,这个cookie还能使用吗?
  3. 3.由于存放JsessionIdcookie被销毁类,所以你找不到原来的session对象类,但是那个对象还会在内存中存在

1.2 Session超时

1.2.1 什么是Session超时
  1. HttpSession的最后一程访问时间和当前时间的差距大于了指定的最大空闲时间,这时服务器就会销毁Session对象。默认的空闲时间为30分钟。

1.2.2 如何修改Session的缺省时间限制
  1. 1 使用HttpSessionsession.setMaxInactiveInterval(20*60);设置,单位秒
  2. 2 web.xml中配置 ,单位分钟
  3. <session-config>
  4. <session-timeout>20</session-timeout>
  5. </session-config>

1.2.3 Session失效的几种情况
  1. 1、超过了设置的超时时间
  2. 2、主动调用了invalidate方法
  3. 3、服务器主动或异常关闭
  4. 注意:浏览器关闭并不会让Session失效
  5. 注意的点:session失效不失session对象被销毁了,他还在内存中,只是不能用了。
  6. 监听器去解决

总结:

  1. 1.session的工作原理
  2. 2.如何去理解session的作用范围是一次会话
  3. 3.sesssio这个对象本质是一个键值对的容器,通过get/setAttribute方法可以往容器中放值取值,这些值的作用范围是一次会话,主要应用,整个web去存放登录信息

2.4 Session的典型应用

2.4.1 验证登录

记得导jar包:

  1. <%--
  2. Created by IntelliJ IDEA.
  3. User: Administrator
  4. Date: 2020/2/27
  5. Time: 11:45
  6. To change this template use File | Settings | File Templates.
  7. --%>
  8. <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="utf-8" %>
  9. <html>
  10. <head>
  11. <title>Title</title>
  12. </head>
  13. <body>
  14. <body>
  15. <form action="login" method="post">
  16. <label>邮箱:</label><input name="email"><br/>
  17. <label>密码:</label><input type="password" name="psw"><br/>
  18. <label>验证码:</label><input type="text" name="code"><br/>
  19. <img src="code" id="img">
  20. <input type="submit" value="登录">
  21. </form>
  22. <script type="text/javascript">
  23. var img=document.getElementById("img");
  24. //这是浏览器的一个缓存问题,静态资源的缓存问题
  25. //表现形式:当链接地址没有发生变化时,他不会去发送请求
  26. var num=1;
  27. img.onclick=function () {
  28. num++;//没有实际的意义,只是去迷惑浏览器,使其认为这不是同一个请求
  29. img.src="code?num="+num;
  30. }
  31. </script>
  32. </body>
  33. </html>
  34. package com.qf.controller;
  35. import cn.dsna.util.images.ValidateCode;
  36. import javax.servlet.ServletException;
  37. import javax.servlet.annotation.WebServlet;
  38. import javax.servlet.http.HttpServlet;
  39. import javax.servlet.http.HttpServletRequest;
  40. import javax.servlet.http.HttpServletResponse;
  41. import java.io.IOException;
  42. public class CodeServlet extends HttpServlet {
  43. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  44. doGet(request,response);
  45. }
  46. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  47. // public ValidateCode(int width, int height, int codeCount, int lineCount)
  48. //width:验证码图片的宽度
  49. //height:验证码图片的高度
  50. //codeCount:验证码的个数
  51. //lineCount:文字行高
  52. ValidateCode vc=new ValidateCode(200,30,4,10);
  53. System.out.println("验证码为"+vc.getCode()+"======================================");
  54. //当同一个session对象重复添加键时,新加的会把原来的覆盖掉
  55. request.getSession().setAttribute("code",vc.getCode());
  56. //将图片通过响应的输出流响应给浏览器展示
  57. vc.write(response.getOutputStream());
  58. }
  59. }
  60. package com.qf.controller;
  61. import com.qf.model.User;
  62. import javax.servlet.ServletException;
  63. import javax.servlet.annotation.WebServlet;
  64. import javax.servlet.http.HttpServlet;
  65. import javax.servlet.http.HttpServletRequest;
  66. import javax.servlet.http.HttpServletResponse;
  67. import java.io.IOException;
  68. public class LoginServlet extends HttpServlet {
  69. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  70. doGet(request,response);
  71. }
  72. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  73. request.setCharacterEncoding("utf-8");
  74. response.setContentType("text/html;charset=utf-8");
  75. String email = request.getParameter("email");
  76. String psw = request.getParameter("psw");
  77. String code = request.getParameter("code");
  78. //想办法拿到原来生成的code,在session里面
  79. String trueCode= (String) request.getSession().getAttribute("code");
  80. if(trueCode.equals(code)){
  81. //模拟去数据库查
  82. //User u=service.login();
  83. User u=new User("zhangsan@qq.com","1234");
  84. if(u!=null){
  85. //登录成功之后一定要记得将登录信息放到session域中
  86. request.getSession().setAttribute("user",u);
  87. response.sendRedirect("index.jsp");
  88. }else{
  89. response.getWriter().println("密码失败");
  90. response.sendRedirect("error.jsp");
  91. }
  92. }else{
  93. response.getWriter().println("验证码失败");
  94. response.sendRedirect("error.jsp");
  95. }
  96. }
  97. }

作业:

  1. 1.总结sessioncookie的区别(重要!重要!重要!)

第二节 过滤器

2.1 什么是过滤器
  1. Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
  2.   Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截。

2.2 如何编写过滤器
  1. 1、编写java类实现Filter接口
  2. 2、重写doFilter方法
  3. 3、设置拦截的url

入门案例:

  1. package com.qf.web.filter;
  2. import javax.servlet.*;
  3. import javax.servlet.annotation.WebFilter;
  4. import java.io.IOException;
  5. /**
  6. * @author wgy 2018/11/28 9:23
  7. * @version 1.0
  8. */
  9. @WebFilter("/myservlet1")//过滤路径
  10. public class MyFilter1 implements Filter {
  11. //初始化过滤器
  12. @Override
  13. public void init(FilterConfig filterConfig) throws ServletException {
  14. System.out.println("过滤器初始化了........init... "+filterConfig);
  15. }
  16. //执行过滤
  17. @Override
  18. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  19. System.out.println("过滤前........doFilter ");
  20. //放行
  21. chain.doFilter(request, response);
  22. System.out.println("过滤后.......doFilter");
  23. }
  24. //销毁
  25. @Override
  26. public void destroy() {
  27. System.out.println("销毁了.....destroy");
  28. }
  29. }

2.3 过滤器的配置

2.3.1 注解式配置

在自定义的Filter类上使用注解@WebFilter(“/*”)

2.3.2 xml配置

在web.xml中进行过滤器的配置:

  1. <!--过滤器的xml配置 -->
  2. <filter>
  3. <!--名称-->
  4. <filter-name>sf</filter-name>
  5. <!--过滤器类全称-->
  6. <filter-class>com.qf.web.filter.SecondFilter</filter-class>
  7. </filter>
  8. <!--映射路径配置-->
  9. <filter-mapping>
  10. <!--名称-->
  11. <filter-name>sf</filter-name>
  12. <!--过滤的url匹配规则和Servlet的一模一样-->
  13. <url-pattern>/*</url-pattern>
  14. </filter-mapping>

2.4 过滤器链

(在资源放行前,过滤请求,在资源放行后,过滤响应,多个过滤器之间过滤成链)

  1. 通常客户端对服务器请求之后,服务器调用Servlet之前会执行一组过滤器(多个过滤器),那么这组过滤器就称为一条过滤器链。
  2. 每个过滤器实现某个特定的功能,一个过滤器检测多个Servlet。(匹配几个,检测几个)。
  3. 一组过滤器中的执行顺序与<filter-mapping>的配置顺序呢有关。
  4. 当第一个FilterdoFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2filter,如果没有,则调用目标资源

2.5 过滤器的优先级
  1. 在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。web服务器根据Filterweb.xml文件中的注册顺序,决定先调用哪个Filter。当第一个FilterdoFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2filter,如果没有,则调用目标资源
  2. 如果为注解的话,是按照类名的字符串顺序进行起作用的
  3. 如果web.xml,按照 filter-mapping注册顺序,从上往下
  4. web.xml配置高于注解方式
  5. 推荐使用xml方式进行配置

2.6 过滤器的初始化参数

在过滤器的创建的时候,可以传递初始化参数

第一种:基于注解的

  1. /**
  2. * Servlet Filter implementation class FirstFilter 创建过滤器
  3. */
  4. @WebFilter(value="/*",initParams= {@WebInitParam(name = "version", value = "1.0")})
  5. public class FirstFilter implements Filter {
  6. /**
  7. * Default constructor.
  8. */
  9. public FirstFilter() {
  10. // TODO Auto-generated constructor stub
  11. }
  12. /**
  13. * @see Filter#destroy() 销毁
  14. */
  15. public void destroy() {
  16. // TODO Auto-generated method stub
  17. System.out.println("destroy销毁……");
  18. }
  19. /**
  20. * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) 过滤
  21. */
  22. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  23. throws IOException, ServletException {
  24. // TODO Auto-generated method stub
  25. // place your code here
  26. System.out.println("doFilter……过滤");
  27. // 是否继续---访问下一个
  28. chain.doFilter(request, response);
  29. }
  30. /**
  31. * @see Filter#init(FilterConfig)
  32. * 初始化
  33. */
  34. public void init(FilterConfig fConfig) throws ServletException {
  35. // TODO Auto-generated method stub
  36. System.out.println("init……初始化");
  37. System.out.println("初始化参数:版本号:"+fConfig.getInitParameter("version"));
  38. }
  39. }

第二种:基于xml配置

  1. /**
  2. * 创建过滤器
  3. */
  4. public class SecondFilter implements Filter {
  5. /**
  6. * Default constructor.
  7. */
  8. public SecondFilter() {
  9. // TODO Auto-generated constructor stub
  10. }
  11. /**
  12. * @see Filter#destroy() 销毁
  13. */
  14. public void destroy() {
  15. // TODO Auto-generated method stub
  16. }
  17. /**
  18. * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) 过滤
  19. */
  20. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  21. throws IOException, ServletException {
  22. // 是否继续---访问下一个
  23. chain.doFilter(request, response);
  24. }
  25. /**
  26. * @see Filter#init(FilterConfig)
  27. * 初始化
  28. */
  29. public void init(FilterConfig fConfig) throws ServletException {
  30. // TODO Auto-generated method stub
  31. System.out.println("初始化参数:版本号:"+fConfig.getInitParameter("version"));
  32. }
  33. }

Web.xml实现配置:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
  3. <display-name>Web_Day</display-name>
  4. <!--过滤器的xml配置 -->
  5. <filter>
  6. <filter-name>myfilter</filter-name>
  7. <filter-class>com.qf.web.filter.SecondFilter</filter-class>
  8. <!--过滤器的初始化参数 -->
  9. <init-param>
  10. <param-name>version</param-name>
  11. <param-value>1.0</param-value>
  12. </init-param>
  13. </filter>
  14. <filter-mapping>
  15. <filter-name>myfilter</filter-name>
  16. <url-pattern>/*</url-pattern>
  17. </filter-mapping>
  18. <welcome-file-list>
  19. <welcome-file>index.html</welcome-file>
  20. </welcome-file-list>
  21. </web-app>

2.7 过滤器的优点

可以实现 Web 应用程序中的预处理和后期处理逻辑

  1. chain.doFilter(req, resp);//资源放行
  2. 如果不去执行这一句话,那么请求就会被拦截,不再继续往下走
  3. 在资源放行的前后,我们可以对请求进行处理和对响应进行处理

2.8 过滤器的典型应用

过滤器的作用来看

  1. 1.过滤所有的请求,因为他是在servlet.jsp.html等资源执行之前执行,可以类似封装的作用,比如处理乱码
  2. 2.可以在资源放行之前,对request进行处理,过滤敏感词
  3. 3.我们可以在资源放行之后,对资源响应给浏览器的response进行相关处理:压缩响应内容

案例1禁用浏览器缓存

web对静态资源有缓存作用(img,html,js,css)

对于目前现在的浏览器,get请求动态资源缓存问题已经解决。

max-age<=0 时 向server 发送http 请求确认 ,该资源是否有修改

对于静态资源部分浏览器使用Cache-Control头和Expires头设置缓存时间。

对于静态资源服务器会采用304状态码控制是否再次发送数据,从而节省带宽;可以通过Cache-Control=no-store,Expires=-1,Pragma=no-cache控制304无效。

  1. package com.qf.filter;
  2. import javax.servlet.*;
  3. import javax.servlet.annotation.WebFilter;
  4. import javax.servlet.http.HttpServletRequest;
  5. import javax.servlet.http.HttpServletResponse;
  6. import java.io.IOException;
  7. public class CacheFilter implements Filter {
  8. public void destroy() {
  9. }
  10. public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
  11. //将req转换成HttpServletRequest
  12. HttpServletRequest request= (HttpServletRequest) req;
  13. HttpServletResponse response= (HttpServletResponse) resp;
  14. //通过以下参数的设置,可以禁用浏览器缓存
  15. response.setDateHeader("Expires",-1);
  16. response.setHeader("Cache-Control","no-store");
  17. response.setHeader("Pragma","no-cache");
  18. chain.doFilter(req, resp);
  19. }
  20. public void init(FilterConfig config) throws ServletException {
  21. //获取初始化参数
  22. String driverClassName = config.getInitParameter("driverClassName");
  23. System.out.println(driverClassName+"============================================");
  24. }
  25. }

作业:如何设置浏览器缓存时间

案例2 自动登录

案例3 过滤脏词

案例4 过滤器解决编码

案例五:对响应内容进行压缩

作业题

  1. 1.总结sessioncookie的区别(重要!重要!重要!)
  2. 2.如何设置浏览器缓存时间
  3. 3.session的工作原理抄写三遍