文章目录
提示:以下是本篇文章正文内容,下面案例可供参考
一、Filter是什么?
webServlet有三大组件:Servlet Filter(过滤器) Listerner (监听器)
生活中中的过滤器有哪些?
净水器的滤芯 空心滤芯 鱼网
网络中拦截器:
有些网站必须是在登录下才能访问,比如咱们测评系统,一打开网址,就是登录页面
必须先登录的一些网站
过滤器有什么作用? 验证信息登录,处理字符问题,过滤跳转等
WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
就是咱们请求一个资源的时候,先通过Filter进行拦截,如果你能符合我的条件我就放行。让你继续去请求资源,如果你不符合我的条件,我就不让你去请求这个资源
二、Filter的入门案例
1.自定义一个类去实现一个接口Fileter
2.重写方法
3.配置Filter
注解写法(只用这种情况)
配置写法
e n d end end没有出来什么意思?index.jsp被拦截了?为什么他被拦截了?过滤器我写的是/*,就意味着所有的
资源都要被拦截。
代码如下(示例):
package com.qfedu.b_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);//放行,先走的是Servlet,再回到我们的过滤器
/*
* if语句,该放行的就写一个chain.doFilter(req,resp);//放行
* 不该放行的话,让他跳转到其它页面
* */
System.out.println("放行完以后资源访问继续");
}
public void init(FilterConfig config) throws ServletException {
System.out.println("FilterDemo1这个过滤器被初始化");
}
}
三、Filter注解和配置文件的写法
优先选择注解写法,方便简单,两者只能选择其一
3.1配置文件的写法
① 需要在web.xml文件写配置
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>FilterDemo2</filter-name>
<filter-class>com.qfedu.b_filter.FilterDemo2</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDemo2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
package com.qfedu.b_filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
public class FilterDemo2 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 {
}
}
3.2注解的写法【推荐使用】
代码如下(示例):
package com.qfedu.b_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);//放行,先走的是Servlet,再回到我们的过滤器
/*
* if语句,该放行的就写一个chain.doFilter(req,resp);//放行
* 不该放行的话,让他跳转到其它页面
* */
System.out.println("放行完以后资源访问继续");
}
public void init(FilterConfig config) throws ServletException {
System.out.println("FilterDemo1这个过滤器被初始化");
}
}
四、Filter的细节处理
4.1Filter的执行流程
浏览器访问资源路径的时候,会先匹配咱们的Filter,会被拦截下面(要么放行,要么拦截)
1.先执行的Filter
2.看是否满足条件
如果你满足我的条件,我就放行,让你去请求下面的资源
如果你不满我的条件,我就拦截,哪里来回那里去
3.放行执行资源,又回到拦截器给客户端响应
4.2Filter的生命周期
和Servlet的生命周期特别像
1.Filter构造方法要执行。实例化了Filter
2.Filter初始化 init
3.doFilter() 核心方法
4.服务器关闭,Filter正常销毁
4.3Filter过滤路径的问题【重点】
设置过滤拦截的路径
1.精准拦截
@WebFilter(“/index.jsp”);拦截的就是index.jsp
@WebFilter(“/test”);拦截的就是test这个资源2.拦截某一个目录
@WebFilter(“/user/*”);拦截uesr下面的所有的资源
3.拦截指定后缀的资源
*.do
*.jsp
*.html4.拦截所有的资源
/*
package com.qfedu.b_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 {
}
}
4.4拦截方式有哪些参数【了解】
@WebServlet() 有很多参数 比如name value urlPatterns loadOnStartup
都不用
@WebFilter()也有参数
firstName value
dispatcherTypes属性是在转发的时候,拦截请求的次数
package com.qfedu.b_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,DispatcherType.FORWARD})
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 {
}
}
4.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 {
}
}
五、过滤器的综合案例
大家使用网站都是什么样的网站,一输入网址就直接跳转到登录页面
大家想一下咱们今天上午写的那个东西,一进来是登录页面?不是的
咱们能不能你写一个请求,无论怎么写?都是进的登录页面?可以的
http://localhost:8080/day43_wb1/sb 也让你跳转到登录页面
和咱们上午写的类似,但是加了过滤器,过滤所有的资源,只放行一个资源login.html
你的网站必须一上去就是登录页面!!!淘宝和京东是半功能性网站。咱们现在要求一进去就是一个登录页面。只是在Filte里面写几个if-else语句,啥时候放行啥时候不放行自己要清楚
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>
LoginServlet.java
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)&&"123456".equals(password)){
//之前将的登录成功以后就直接跳转到主页面了,但是现在
//我再做一件事,把"张三"存到session中
//1.创建session对象
HttpSession session = request.getSession();
//2.获取当前session对象的id 服务器对session唯一的标识
String id = session.getId();
//3.创建cookie对象,键叫做JSESSIONID 值 id
Cookie cookie = new Cookie("JSESSIONID", id);
//设置cookie的有效时间
cookie.setMaxAge(60*60*24);
//4.发送到浏览器进行保存
response.addCookie(cookie);
//5.设置session的值
session.setAttribute("user","张三");
//6.一旦session有值,重定向到IndexServlet
//跳转到主页面
response.sendRedirect("IndexServlet");
}else{
response.sendRedirect("login.html");
}
}
}
IndexServlet.java:
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='red'>欢迎"+session.getAttribute("user")
+"来到澳门皇冠洗浴中心<font><br>";
html += "<a href='ExitServlet' style='color:pink;font-size=20px'>退出</a>";
response.getWriter().append(html);
}
}
ExitServlet.java:
package com.qfedu.Servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
@WebServlet("/ExitServlet")
public class ExitServlet 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();
if (session != null){
//销毁session
session.invalidate();
//销毁cookie
Cookie cookie = new Cookie("JSESSIONID", "");
cookie.setMaxAge(0);//这样才是销毁cookie
//发送到浏览器进行保存
response.addCookie(cookie);
//销毁以后重定向到login.html
response.sendRedirect("login.html");
}
}
}
LoginFilter.java:
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");
//获取session
HttpSession session = ((HttpServletRequest) req).getSession();
System.out.println(session);
//如果session为null,就跳转到登录页面
//http://localhost:8080/day43_xkh2/IndexServlet
//http://localHost:8080/day43_xkh2/login.html放行
//http://localhost:8080/day43_xkh2/LoginServlet放行,最后也是跳转到login.html
//获取url的一部分/day43_xkh2/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 {
}
}
结果如下(示例):
程序点击运行,就直接跳转到登录界面
输入姓名:张三 密码:123456
点击登录,就跳转到主页面了
点击退出,跳转到登录页面
总结
提示:这里对文章进行总结:
以上就是今天要讲的内容.