2021年9月14日

今天的内容

1.URL匹配规则

2.ServletContext对象【重点】

3.Request对象

4.Response对象

5.Cookie和Session【重点!!!开发要用的】

1.URL的匹配规则

@WebServlet("/test")

/test就是咱们某一个资源的路径写法

用户申请了一个资源

http://localhost:8080/day41_wb/LoginServlet

1.http协议

2.localhost 本地服务器主机的名字

3.8080端口号

4.day41_wb/LoginServlet是咱们所申请的资源

day41_wb/当前应用程序目录,就是程序的绝对路径

LoginServlet 申请的资源

url匹配原则:

1.精准匹配

比如 /资源名字@WebServlet("/test.do")

2模糊匹配符

比如 @WebServlet("*.do") 以.do为后缀的资源都可以进行访问

比如@WebServlet("/*") 所有资源都可以访问

package com.qfedu.a_servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

//精准匹配,通过你写的@WebServlet真实的值,去找到你所对应的资源
@WebServlet("/TestServlet1")
public class TestServlet1 extends HttpServlet {
   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       doGet(request, response);
  }

   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       response.setContentType("text/html;charset=utf-8");
       response.getWriter().append("这个是精准匹配");
  }
}
package com.qfedu.a_servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


//这个模糊匹配是以后缀是.do的资源
//进行匹配的时候在web应用程序下面,.do可以随意些就可以找到这个资源了
//注意*前面没有加斜线
//@WebServlet("*.do")
public class TestServlet2 extends HttpServlet {
   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       doGet(request, response);
  }

   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       response.setContentType("text/html;charset=utf-8");
       response.getWriter().append("这个是模糊匹配里面的一种 以.do后缀的匹配");

  }
}
package com.qfedu.a_servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

//模糊匹配的另外一种写法,就是在/后面随意写就可以了!!!
//以后会用,在将过滤器的时候使用。
//@WebServlet("/*")
public class TestServlet3 extends HttpServlet {
   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       doGet(request, response);
  }

   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       response.setContentType("text/html;charset=utf-8");
       response.getWriter().append("我这个是随意的资源访问,url写啥都可以给你匹配到");
  }
}

2.ServletContext【重要】

ServletContext接口,实例化以后是一个对象,

是咱们当前应用程序可以使用的唯一对象。

在一个Servlet里面,使用另外一个Servlet的提供的数据,怎么办?转发,但是不用用转发怎么办?需要使用ServletContext对象,是全局的。比如你在一个Servlet里面设置一个数据,想要在另外一个Servlet里面使用这个数据,没办法。但是可以通过ServletContext这个接口,这个对象是全局的。如果你在一个Servlet里面使用servletContext 对象设置一个数据,在另外一个Servlet里面也可以通过ServletContext这个对象获取这个数据

两个Servlet依靠servletContext对象进行通信,分享一些数据

package com.qfedu.b_servletContext;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/context1.do")
public class ContextServlet1 extends HttpServlet {
   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       doGet(request, response);
  }

   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       //要使用一个对象,这个对象可以实现servlet之间的共享数据
       //1.获取servletContext对象没当前上下文对象
       ServletContext servletContext = request.getServletContext();
       //2.给当前上下文对象设置一部分数据
       servletContext.setAttribute("msg", "我是Context1对象");
       servletContext.setAttribute("person", new Person("老邢", 78));
       String serverInfo = servletContext.getServerInfo();//返回的是当前Servlet的详细信息
       String contextPath = servletContext.getContextPath();//项目的根目录(以后出现404可以先找这个根目录然后再一点一点的找)

       System.out.println(serverInfo);
       System.out.println(contextPath);
  }
}
package com.qfedu.b_servletContext;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/context2.do")
public class ContextServlet2 extends HttpServlet {
   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       doGet(request, response);
  }

   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       response.setContentType("text/html;charset=utf-8");//处理响应的中文乱码
       //这个Servlet是获取当前上下文对象存的数据
       //1.获取当前上下文对象
       ServletContext servletContext = request.getServletContext();
       Object msg = servletContext.getAttribute("msg");
       System.out.println(msg);
       Person person = (Person)servletContext.getAttribute("person");
       System.out.println(person);

       response.getWriter().append(" "+msg);
  }
}

3.Request对象

ServletReuqest接口

用户访问服务器,服务器会生成一个对象包含了http所有请求头

由于使用的是http协议,HttpServletRequest

3.1RequestAPI

getRequestURL(); 获取完成的url

getRequestURI();获取资源名字

getQueryString();获取一个url参数部分

getRemoteAddr();返回的是客户端的ip地址

getRemoteUser();返回的是客户端的用户

getRemotePort();返回的是客户端的主机的端口号

getRemoteHost();返回的是客户端的主机地址

getCookie();获取CookieD对象

getSession();获取Session对象

getLocalName();获取Web服务器主机的名字

getServletContext();获取上下文对象的

setCharacterEncoding();设置编码集的

getParameter();获取前端传过来的数据的

setAttribute();将数据设置给request对象

getAttribute();获取request对象中的数据的

package com.qfedu.c_request;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/request2")
public class RequestServlet2 extends HttpServlet {
   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       doGet(request, response);
  }

   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       String remoteAddr = request.getRemoteAddr();
       String remoteHost = request.getRemoteHost();
       String remoteUser = request.getRemoteUser();
       int remotePort = request.getRemotePort();
       System.out.println(remoteAddr);//ip地址
       System.out.println(remoteHost);//主机的地址
       System.out.println(remoteUser);//用户名字
       System.out.println(remotePort);//端口号
       //以上代码如果你们在同一个网段是可以测试的
       //写完这个代码以后,你把ip地址告诉你室友,让他去访问你写的这个资源
       //http://10.8.199:8080/day41_wb/request2
       //发现打印的都是别人访问的东西。意味着从这地方知道,
       //你想黑军方的网站,是不可能,你在哪都能找到你,让后关起来,审判,枪毙
       //以后开发必用的!!!是以下的方法
//       String name = request.getParameter("name");//获取前段传过来的数据
//       request.setCharacterEncoding("utf-8");//请求设置编码集
//       request.getRequestDispatcher("index.jsp").forward(request, response);//转发的代码
//       request.setAttribute("name", "狗蛋");
//       request.getAttribute("name");
       //request.getServletContext();//获取上文对象的
  }
}

4.Response对象

响应对象,把数据给客户端

咱们的Servlet紧紧围绕着两个点学习(Request, Response)请求和响应

setHeader(); 设置响应头的参数

setContentType();设置字符编码集

getWriter();获取字符输出流对象

addCoookie(); 对浏览器新增一个Cookie

sendRedirect();重定向

5.Cookie和Session

http是一种无状态的访问

浏览器发送请求到服务器,服务器给与一定的响应,但是断开连接以后,如果服务器更新了,如果服务器没有发送任请求,是没有任何响应的

这个就是无状态的访问:

实际操作中存在一定的问题:

比如登录一个网站以后,再次跳转到这个网站的其他页面,他是不会保持第一个页面的状态的,这叫无状态的。

登录一个页面的话,他不会保证上一页面的状态,如何来保持上一个页面的状态的呢?靠咱们即将要讲的会话技术(Cookie和Session),才能保持上一个页面的状态!!!

如果没有cookie和session的话,http协议是一个无状态的协议,你每一个跳转到下一个页面的时候都是需要先登录的,这就很麻烦了。

比如淘宝(cookie和session的话),登录上去了,(需要登录才能)选择商品,(需要登录)放到购物车,(需要登录)然后购买,这样用户的体验是相当差的然后才有咱们即将要讲的会话控制。会话控制的目的就是为了点击页面的时候,保持上面一个页面的状态

5.1会话技术

cookie:

浏览器保存的内容,通常cookie是在浏览器中保存的,每一次访问服务器的时候,浏览器会自动的把cookie带到下一个页面。

cookie的大小时有限制,通常是4096byte.

cookie信息中不能有中文

cookie的保存是以键值对形式存在的

session:

保存服务器中,每一个session在咱们当前的服务器会有一个标识号,

会保存浏览器访问服务器的一些记录信息,没有大小的限制

可以保存中文

信息的保存也是以键值对形式存在的

5.2Cookie

如果想要使用cookie要保证咱们的浏览器是开启cookie,所以说有一定的弊端,如果浏览器cookie关了,关了就不能再使用cookie了

常用的API

1.cookie的构造方法,目的是实例化出来cookie对象

Cookie(String name, String value);

2.设置cookie的方法

setValue(String value);修改cookie的值

setMaxAge(int time);设置cookie的有效时间

setPath(String path);设置当前cookie的有效路径

3.要将cookie发送到浏览器

response.addCookie(Cookie cookie);

先给浏览器设置cookie,获取cookie,销毁cookie,获取cookie(销毁cookie以后还有没有cookie)

设置cookie

package com.qfedu.d_cookie;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/cookie")
public class CookieServlet extends HttpServlet {
   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       doGet(request, response);
  }

   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       //1.创建cookie对象
       //将键 是java2109 值是shengjie实例出来,存到cookie对象中
       Cookie cookie = new Cookie("java2109", "shujie");
       //2.s设置有效时间,如果不设置有效时间,没有关闭浏览器,cookie一直在的
      /*
      * 正数:表示当前cookie的有效时间
      * 负数:表示当前浏览器打开的时候存在,关闭时候的没了
      * 0:销毁当前的cookie
      * */
       cookie.setMaxAge(60*60*24);//设置了有效期是个正数,即使你
       //关闭了浏览器,也可以获取cookie值,可以自动登录的东西
      // cookie.setPath("/day42_wb");
       //3.把cookie发送给浏览器
       response.addCookie(cookie);

  }
}

获取cookie

package com.qfedu.d_cookie;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/getCookie")
public class GetCookieServlet extends HttpServlet {
   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       doGet(request, response);
  }

   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       //获取浏览器中cookie,返回值是一个数组
       Cookie[] cookies = request.getCookies();
       for (Cookie cookie : cookies) {
           //两个
           // JSESSION
           //java2109
           //浏览器一旦关闭cookie就没了
           System.out.println(cookie.getName());//获取键
           System.out.println(cookie.getValue());//获取值
           System.out.println("================");
      }

  }
}

销毁cookie

package com.qfedu.d_cookie;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/destroyCookie")
public class DestroyServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //退出登录
        Cookie[] cookies = request.getCookies();//获取cookie
        for (Cookie cookie : cookies) {
            //JSESSION
            //java2109
            if(cookie.getName().equals("java2109")) {
                cookie.setMaxAge(0);//销毁cookie
                //重新发送给浏览器
                response.addCookie(cookie);
            }
        }
    }
}

先设置cookie,然后得到cookie,然后销毁cookie,得到cookie

5.3Session

为什么使用session?

1.cookie保存数据类型是单一的,只能保存字符串类型的数据,不能有中文

2.cookie的大小有限制

Session可以解决以上Cookie的问题

在java中 session一般结合cookie使用

1.使用session的时候一般要开启cookie

2.如果浏览器没有开启cookie功能,咱们可以通过html的url传参完成session的使用

Session的API

getSession();获取session对象的

getId();JSESSIONID(在cookie里面) 服务器下面一个标识号,session存在服务器中其中JSESSION是服务器下面的一个标识。

invalidate();销毁session

setMaxInactiveInterval();设置过期时间

setAttribute();设置session的内容

getAttribute();得到session的内容

往session里面存值,取值,销毁,再取值。让下一页面可以获取到session里面来保持下一个页面的转态

比如登录以后,用户名存到session,在咱们跳转到主页,在主页里面可以把session里面用户名字取出来展示到咱们主页面

package com.qfedu.a_session;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

//向session中存数据
@WebServlet("/setSession")
public class SessionTestServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取session对象
        HttpSession session = request.getSession();
        System.out.println(session);
        //获取的是JSESSIONID  服务器唯一的标识
        System.out.println(session.getId());
        //给session设置一个过期时间,有效果的!!!
        session.setMaxInactiveInterval(60*60*24);
        session.setAttribute("name", "王博");
    }
}
package com.qfedu.a_session;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/getSession")
public class GetSessionServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取session对象
        //第一次创建session的时候默认的true,
        //fasle的话,这个session使用的已经创建好的session对象
        HttpSession session = request.getSession(false);
        //2.获取session,通过键取值
        Object name = session.getAttribute("name");
        System.out.println(name);
    }
}
package com.qfedu.a_session;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

//销毁session
@WebServlet("/destSession")
public class DestroyServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession(false);//当session存在的时候写一个false
        session.invalidate();//销毁当前的session
    }
}

5.4自动登录

结合cookie和session一起,写一个自动登录案例

自动登录实现

package com.qfedu.b_auto_login;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * 判断session是否有值?如果有值就直接跳转到主页面
 * 如果没有session里面没有值,那就跳转到登录页面
 * 。在登录页面之后,在存到session里面
 */
@WebServlet("/IndexServlet")
public class IndexServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //响应乱码的解决方法
        response.setContentType("text/html;charset=utf-8");
        //写个if语句,判断session里面是否有值
        //1.获取session对象,证明已经有session对象了
        HttpSession session = request.getSession(false);
        //2.判断session里面存的值 "老邢" 字符串写死了,
        //判断session和数据库里面是否一致
        System.out.println(session);
        if(session != null && session.getAttribute("user").equals("老邢")) {
            //session 存的有值的情况
            String html = "<font size='7' color='green'>欢迎"+ session.getAttribute("user")+"来到直播间</font><br>";
            html += "<a href='LogoutServlet' style='color:pink;font-size=20px'>退出</a>";
            response.getWriter().append(html);
        }else {
            //session里面存的没有值的情况
            //如果没有值,就登录
            //重定向到login.html
            response.sendRedirect("login.html");
        }

    }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<form action="LoginServlet" method="post">
    姓名:<input type="text" name="user"><br>
    密码:<input type="password" name="password"><br>
    <input type="submit" value="登录">

</form>

</body>
</html>
package com.qfedu.b_auto_login;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;

@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取前端传过来的数据html页面取过来啊
        //一位是post请求,我怕请求乱码
        request.setCharacterEncoding("utf-8");
        String user = request.getParameter("user");
        String password = request.getParameter("password");
        //验证登录信息。连上数据,写一个sql语句判断user和password
        //现在我不写了,你们来写,我写的是死数据
        //"老邢"  数据库拿出来,但是我现在只写一个字符串写死了
        if("老邢".equals(user) && "123".equals(password)) {
            //之间讲的登录成功以后就直接跳转到主页面了,但是现在
            //我再做一件事情,做把"老邢"存到sesssion中
            //1.创建session的对象
            HttpSession session = request.getSession();
            //2.获取当前session对象的id  服务器对session唯一的标识
            String id = session.getId();
            //3.创建cookie对象,键叫JESSIONID  值 id
            Cookie cookie = new Cookie("JSESSIONID", id);
            cookie.setMaxAge(60*60);
            //4.发送给浏览器进行保存
            response.addCookie(cookie);
            //5.设置session的值
            session.setAttribute("user", "老邢");
            //6.一旦session有值,重定向到IndexServlet
            //跳转到主页面了
            response.sendRedirect("IndexServlet");

        } else{
            response.sendRedirect("login.html");
        }
    }
}
package com.qfedu.b_auto_login;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;

/**
 * 销毁cookie和session
 */
@WebServlet("/LogoutServlet")
public class LogoutServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取session对象
        HttpSession session = request.getSession(false);
        if (session != null) {
            session.invalidate();//销毁session
        }
        //销毁cookie
        Cookie cookie = new Cookie("JSESSIONID", "");
        cookie.setMaxAge(0);//才能是销毁cookie
        response.addCookie(cookie);
        //销毁以后重定向到login.html
        response.sendRedirect("login.html");


    }
}

首先写一个IndexServlet判断是否有session,如果有session就响应页面

如果没有session的话,就跳转到login.html,点击登录按钮,又跳转到了LoginServet

LoginServlet里面连接数据库判断是否登录成功,还做了一件事情,把用户名存到session里面

是因为咱们的IndexServlet里面是否有值。

6.过滤器【重点】

webServlet有三大组件:Servlet Filter(过滤器) Listerner (监听器)

6.1Filter概述

生活中中的过滤器有哪些?

净水器的滤芯 空心滤芯 鱼网

网络中拦截器:

有些网站必须是在登录下才能访问,比如咱们测评系统,一打开网址,就是登录页面

必须先登录的一些网站 过滤器有什么作用?

验证信息登录,处理字符问题,过滤跳转等

WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

就是咱们请求一个资源的时候,先通过Filter进行拦截,如果你能符合我的条件我就放行。让你继续去请求资源,如果你不符合我的条件,我就不让你去请求这个资源

6.2Filter的快速入门

1.自定义一个类去实现一个接口Fileter

2.重写方法

3.配置Filter

注解写法(只用这种情况)

配置写法

$end$没有出来什么意思?index.jsp被拦截了?为什么他被拦截了?过滤器我写的是/*,就意味着所有的

资源都要被拦截。

package com.qfedu.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

//@WebFilter("/*")   我要去拦截你所有的资源
@WebFilter("/*")
public class FilterDemo1 implements Filter {
    //写着构造方法的目的,是为了让你知道这个FilterDemo1被实例化了没
    public FilterDemo1() {
        System.out.println("我是FilterDemo1的构造方法");
    }
    public void destroy() {
        System.out.println("FilterDemo1这个过滤器被销毁");
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //是核心方法,一般的业务逻辑写在这个地方
        System.out.println("doFilter called....");
        //  chain.doFilter(req, resp);   放行代码,
        //如果这个地方没有写 chain.doFilter(req, resp); 代码走到这个地方
        //被拦截了,不再往下走了
        //chain.doFilter(req, resp);
        chain.doFilter(req,resp);//放行,先走的是Servlet,再回到咱们过滤器
        /*
        * if语句, 该放行的就写一个  chain.doFilter(req,resp);//放
        * 不该放行的话,让他跳转到其他页面
        * */
        //这个代码是servlet执行完以后你才去执行
        System.out.println("放行以后资源访问继续");
    }

    public void init(FilterConfig config) throws ServletException {
        System.out.println("FilterDemo1这个过滤器被初始化");
    }

}

配置写法

Servlet也是有两种写法,一种注解写法,一种配置写法。但是只使用注解写法,注解写法太爽了

Filter也是有两种写法,一种注解写法,一种配置写法。咱们也用注解写法太爽了。

在WEB-INF里面有一个web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <filter>
        <filter-name>FiterDemo1</filter-name>
        <filter-class>com.qfedu.filter.FilterDemo1</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>FiterDemo1</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

6.3Filter的细节处理

6.3.1Filter执行流程

浏览器访问资源路径的时候,会先匹配咱们的Filter,会被拦截下面(要么放行,要么拦截)

1.先执行的Filter

2.看是否满足条件

如果你满足我的条件,我就放行,让你去请求下面的资源

如果你不满我的条件,我就拦截,哪里来回那里去

3.放行执行资源,又回到拦截器给客户端响应

请求-》filter-》servlet-》filter-》响应

6.3.2Filter的生命周期

和Servlet的生命周期特别像

1.Filter构造方法要执行。实例化了Filter

2.Filter初始化 init

3.doFilter() 核心方法

4.服务器关闭,Filter正常销毁

6.3.3Filter过滤路径的问题【重点】

设置过滤拦截的路径

1.精准拦截

@WebFilter("/index.jsp"); 拦截的就是index.jsp

@WebFilter("/test"); 拦截的就是/test

2.拦截某一个目录

@WebFilter("/user/*") 拦截/user下面的所有的资源

3.拦截指定后缀的资源

*.do *.jsp *.html

4.拦截所有的资源 /*

package com.qfedu.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

//精准拦截
//@WebFilter("/index.jsp")
//@WebFilter("/test")
//@WebFilter("/user/*")拦截/user下面所有的资源
//@WebFilter("*.jsp")//拦截后缀为.jsp都拦截
//@WebFilter("/*")//拦截所有的资源,讲案例的时候会用!!!
public class FilterDemo3 implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {

    }

}
6.3.4拦截方式有哪些参数【了解】

@WebServlet() 有很多参数 比如 name value urlPatterns loadOnStartup

都不用

@WebFilter()也有参数

filterName value

dispatcherTypes属性是在转发的时候,拦截请求的次数
package com.qfedu.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

/*
* value 拦截哪些资源
*dispatcherTypes 和咱们转发有关  但是真实开发不用
*dispatcherTypes = {DispatcherType.REQUEST} 如果是这个参数,请求被拦截一次
* 因为转发在服务器中就是一次请求
* dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD}
* 如果是这个参数,请求被拦截俩次,转发到test.jsp这个页面也是需要被拦截
* */
@WebFilter(value = "/*", dispatcherTypes = {DispatcherType.REQUEST})
public class FilterDemo4 implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //请求被拦截
        System.out.println("请求被拦截");
        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {

    }

}
6.3.5过滤器链【了解】

如果有多个过滤到底谁先执行呢?

多个过滤器的时候,执行的顺序是非常随意的,按照字符串进行比较,升序进行的

AFilter BFilter 是先AFilter 再BFilter

数字的话,先执行1 再执行2

FilterDemo5........ FilterDemo6...... FilterDemo6!!!! FilterDemo5 !!!!!

package com.qfedu.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter( "/*")
public class FilterDemo5 implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("FilterDemo5........");
        chain.doFilter(req, resp);
        System.out.println("FilterDemo5  !!!!!");
    }

    public void init(FilterConfig config) throws ServletException {

    }

}
package com.qfedu.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter("/*")
public class FilterDemo6 implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("FilterDemo6......");
        chain.doFilter(req, resp);
        System.out.println("FilterDemo6!!!!");
    }

    public void init(FilterConfig config) throws ServletException {

    }

}

7.过滤器的综合案例

大家使用网站都是什么样的网站,一输入网址就直接跳转到登录页面

大家想一下咱们今天上午写的那个东西,一进来是登录页面?不是的

咱们能不能你写一个请求,无论怎么写?都是进的登录页面?可以的

http://localhost:8080/day43_wb1/sb 也让你跳转到登录页面

和咱们上午写的类似,但是加了过滤器,过滤所有的资源,只放行一个资源login.html

你的网站必须一上去就是登录页面!!!淘宝和京东是半功能性网站。咱们现在要求一进去就是一个登录页面。只是在Filte里面写几个if-else语句,啥时候放行啥时候不放行自己要清楚

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="LoginServlet" method="post">
    姓名:<input type="text" name="user"><br>
    密码:<input type="password" name="password"><br>
    <input type="submit" value="登录">

</form>
</body>
</html>
package com.qfedu.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;

@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取前端传过来的数据html页面取过来啊
        //一位是post请求,我怕请求乱码
        request.setCharacterEncoding("utf-8");
        String user = request.getParameter("user");
        String password = request.getParameter("password");
        //验证登录信息。连上数据,写一个sql语句判断user和password
        //现在我不写了,你们来写,我写的是死数据
        //"老邢"  数据库拿出来,但是我现在只写一个字符串写死了
        if("老邢".equals(user) && "123".equals(password)) {
            //之间讲的登录成功以后就直接跳转到主页面了,但是现在
            //我再做一件事情,做把"老邢"存到sesssion中
            //1.创建session的对象
            HttpSession session = request.getSession();
            //2.获取当前session对象的id  服务器对session唯一的标识
            String id = session.getId();
            //3.创建cookie对象,键叫JESSIONID  值 id
            Cookie cookie = new Cookie("JSESSIONID", id);
            cookie.setMaxAge(60*60);
            //4.发送给浏览器进行保存
            response.addCookie(cookie);
            //5.设置session的值
            session.setAttribute("user", "老邢");
            //6.一旦session有值,重定向到IndexServlet
            //跳转到主页面了
            response.sendRedirect("IndexServlet");

        } else{
            response.sendRedirect("login.html");
        }
    }
}
package com.qfedu.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/IndexServlet")
public class IndexServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        //还需要判断session吗?不需要判断了,因为咱们的过滤掉了,过滤器过滤的就是
        //session 为空的情况,所以这个地方不用再判断session是否为空了
        //session 存的有值的情况

        HttpSession session = request.getSession(false);
        String html = "<font size='7' color='green'>欢迎"+ session.getAttribute("user")+"来到直播间</font><br>";
        html += "<a href='LogoutServlet' style='color:pink;font-size=20px'>退出</a>";
        response.getWriter().append(html);
    }
}
package com.qfedu.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;

@WebServlet("/LogoutServlet")
public class LogoutServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取session对象
        HttpSession session = request.getSession(false);
        if (session != null) {
            session.invalidate();//销毁session
        }
        //销毁cookie
        Cookie cookie = new Cookie("JSESSIONID", "");
        cookie.setMaxAge(0);//才能是销毁cookie
        response.addCookie(cookie);
        //销毁以后重定向到login.html
        response.sendRedirect("login.html");
    }
}
package com.qfedu.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/*
* 先拦截你所有资源,然后放行login.html
* */
@WebFilter("/*")
public class LoginFilter implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //符合login.html我就放行,其他不放行
        System.out.println("doFilter");
        HttpSession session = ((HttpServletRequest) req).getSession(false);
        System.out.println(session);//如果session为null,就到登录页面
        //http://localhost:8080/da43_wb2/IndexServlet
        //http://localhost:8080/da43_wb2/login.html  放行
        //http://localhost:8080/da43_wb2/LoginServlet  放行  最终也是跳转到login.html
        //获取url的一部分da43_wb2/IndexServlet
        String requestURI = ((HttpServletRequest) req).getRequestURI();
        System.out.println(requestURI);//统一资源标识符
        //登录相关的资源,不应该过滤的可以放行
        if(requestURI.endsWith("/login.html") || requestURI.endsWith("/LoginServlet")) {
            //放行
            chain.doFilter(req, resp);
        }else if (session == null || session.getAttribute("user") == null) {
            //不能放行,session为空,就证明你没有登录过,所以不能放行
            //跳转到登录页面
            ((HttpServletResponse)resp).sendRedirect("login.html");
        }else if(session != null && session.getAttribute("user")!= null){
            //session不为空,且session里面的值也不为空,就方法,证明你登录过了!!!
            //放行
            chain.doFilter(req, resp);
        }

    }

    public void init(FilterConfig config) throws ServletException {

    }

}



posted @ 2021-09-15 19:09  张三疯321  阅读(68)  评论(0)    收藏  举报