【Jsp】第五课 过滤器的概念与使用

2024-05-11 17:18

本文主要是介绍【Jsp】第五课 过滤器的概念与使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

概念

什么是过滤器?
Filter也称之为过滤器
        
过滤器本质上就是一个特殊的类

通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截。

Servlet过滤器负责过滤的web组件有servletJSP或者是HTML文件,其过滤过程如下图

Servlet过滤器具有以下特点

         Servlet过滤器可以检查和修改requestresponse对象

        可以指定servlet过滤器和特定的URL关联,只有当客户请求访问此URL时,才会触发过滤器工作

        独立servlet过滤器可以被串联在一起,形成管道效应,协同修改请求和响应对象

过滤器的生命周期

servlet 过滤器的生命周期和前面学习的 servlet 一样,包含以下几个阶段:
实例化:在访问 web 资源之前创建过滤器的实例
初始化: web 容器在调用过滤器的 doFilter () 方法之前调用 init() 方法,把 FilterConfig 对象作为参数传给 init() 方法
过滤:每当用户提交请求或 web 资源发送响应时,调用 doFilter () 方法
销毁:在停止使用过滤器之前,用容器调用过滤器的 destory () 方法,完成必要的清除和释放资源

过滤器的API

所有的servlet过滤器都必须实现javax.servlet.Filter接口,在这个接口里定义了3个过滤器必须实现的方法  

Init() 方法 :
@Overridepublic void init(FilterConfig config) throws ServletException {System.out.println("加载初始化的数据");}
doFilter () 方法:
@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {System.out.println("我是MyFilter开始拦截请求地址");}

 destory()方法

@Overridepublic void destroy() {System.out.println("销毁过滤器");}

部署servlet过滤器

部署servlet过滤器,必须要web.xml文件中加入<filter>元素和< filter—mapping>元素  

<filter><filter-name>MyFilter</filter-name><filter-class>com.filter.MyFilter</filter-class></filter><filter-mapping><filter-name>MyFilter</filter-name><url-pattern>/Servlet1</url-pattern></filter-mapping>

 过滤器的使用

我们创建一个新的动态网站项目,在src中新建包,包名为com.servlet,在包中新建Servlet,类名为Servlet1,在Servlet1中的doget方法里编写以下代码:

package com.servlet;import java.io.IOException;
import java.io.PrintWriter;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** Servlet implementation class Servlet1*/
@WebServlet("/Servlet1")
public class Servlet1 extends HttpServlet {private static final long serialVersionUID = 1L;/*** @see HttpServlet#HttpServlet()*/public Servlet1() {super();// TODO Auto-generated constructor stub}/*** @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)*/protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html");response.setCharacterEncoding("UTF-8");PrintWriter pw=response.getWriter();pw.print("我是第一个Servlet");}/*** @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)*/protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubdoGet(request, response);}}

这里我们就可以运行服务端项目使用浏览器地址访问该Servlet1,这是之前的课程中所讲过的,那么今天我们讲在浏览器访问Servlet之前,做访问拦截,接下来,在src中新建包,com.filter,在包中新建class,类名为MyFilter,并实现Filter接口,代码如下:

package com.filter;import java.io.IOException;
import java.io.OutputStream;import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;public class MyFilter implements Filter {{System.out.println("过滤器开始被创建对象");}@Overridepublic void destroy() {System.out.println("销毁过滤器");}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {System.out.println("我是MyFilter开始拦截请求地址");}@Overridepublic void init(FilterConfig config) throws ServletException {System.out.println("加载初始化的数据");}}

 接着需要将该过滤器在web.xml文件中进行注册

<filter><filter-name>MyFilter</filter-name><filter-class>com.filter.MyFilter</filter-class></filter><filter-mapping><filter-name>MyFilter</filter-name><!-- 这里设置的是要拦截的请求地址--><url-pattern>/Servlet1</url-pattern></filter-mapping>

接下来运行,通过浏览器访问Servlet1,会发现不再显示内容,访问请求被过滤器拦截了,得不到过滤器的验证放行,请求是不会进入Servlet1,如果需要放行,只需要加上以下代码即可:

@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {//过滤器允许浏览器的请求地址进入servlet   放行chain.doFilter(request, response);System.out.println("我是MyFilter开始拦截请求地址");}

 那如果我们有三个Servet,分别问Servlet1,Servlet2,Servlet3,在浏览器访问该三个servlet时,都想要先通过过滤器的验证,而这三个过滤器的访问的虚拟地址都不一样,怎么操作才能使用一个过滤器拦截三个不同Servlet的地址请求?

如果大家还有印象,这里我们在第二章就讲过,完全匹配,目录匹配,后缀名匹配。这里需要匹配三个不同的完全匹配地址,我们只需要将拦截器的拦截地址设置为/* 便可以拦截掉所有Servlet的访问请求,这里初学者自行更改代码,运行演示。

流程图如下:

这里有初学者可能很不理解,过滤器在实际开发过程中有什么作用?那么就拿我们刚刚的案例来说,我们刚刚建了Servlet1,现在我们补充一下Servlet2,Servlet3的代码:

package com.servlet;import java.io.IOException;
import java.io.PrintWriter;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** Servlet implementation class Servlet2*/
@WebServlet("/Servlet2")
public class Servlet2 extends HttpServlet {private static final long serialVersionUID = 1L;/*** @see HttpServlet#HttpServlet()*/public Servlet2() {super();// TODO Auto-generated constructor stub}/*** @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)*/protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html");response.setCharacterEncoding("UTF-8");PrintWriter pw=response.getWriter();pw.print("我是第二个Servlet");}/*** @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)*/protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubdoGet(request, response);}}

 

package com.servlet;import java.io.IOException;
import java.io.PrintWriter;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** Servlet implementation class Servlert3*/
@WebServlet("/Servlet3")
public class Servlet3 extends HttpServlet {private static final long serialVersionUID = 1L;/*** @see HttpServlet#HttpServlet()*/public Servlet3() {super();// TODO Auto-generated constructor stub}/*** @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)*/protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html");response.setCharacterEncoding("UTF-8");PrintWriter pw=response.getWriter();pw.print("我是第三个Servlet");}/*** @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)*/protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubdoGet(request, response);}}

我们发现三个Servlet回复数据给浏览器的时候都要经过编码格式的转换的两行代码:

 

 

 

那如果我们做一个项目,需要用到成百上千个Servlet,那么每一个Servlet中都要加这两行代码,那我们开发者的工作量就大大增加了很多,浪费了很多精力和时间,这时候过滤器的作用就来了,既然我们可以使用过滤器拦截所有请求,那就可以在过滤器中进行设置Servlet共用的需求代码,则可以改为如下形式:

将这两行代码抽取至过滤器中执行

 那三个Servlet中的这两行代码就可以删除了,运行演示效果应该是和之前一样的。

多个过滤器串联使用

 

使用Java注解方式创建过滤器

选中过滤器的包,点右键--》new--》filter,创建三个过滤器,设置类名分别为MyFilter1,MyFilter2,MyFilter3,并将拦截请求都设置为/Servlet2,多个过滤器必须拦截的是同一个地址才能起到串联的效果。 那么既然是串联,就涉及到过滤器执行的先后顺序,谁先执行,谁后执行?

多个过滤器想要拦截一个访问地址,这里需要将多个过滤器的拦截地址设置为同一个
那么当多个过滤器拦截访问地址的时候,先被谁拦截?
1.如果多个过滤器都是使用web.xml文件的方式注册的,哪个过滤器先被注册就会先被哪个过滤器拦截

2.如果多个过滤器都是使用java注解的方式注册的,这些过滤器会按照类的名称进行排序访问

 初学者自行编写代码,自行演示效果。

package com.filter;import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;/*** Servlet Filter implementation class MyFilter1*/
@WebFilter("/Servlet2")
public class MyFilter1 implements Filter {/*** Default constructor. */public MyFilter1() {// TODO Auto-generated constructor stub}/*** @see Filter#destroy()*/public void destroy() {// TODO Auto-generated method stub}/*** @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)*/public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("我是MyFilter1开始拦截请求地址");response.setContentType("text/html");response.setCharacterEncoding("UTF-8");chain.doFilter(request, response);}/*** @see Filter#init(FilterConfig)*/public void init(FilterConfig fConfig) throws ServletException {// TODO Auto-generated method stub}}

 

package com.filter;import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;/*** Servlet Filter implementation class MyFiler2*/
@WebFilter("/Servlet2")
public class MyFiler2 implements Filter {/*** Default constructor. */public MyFiler2() {// TODO Auto-generated constructor stub}/*** @see Filter#destroy()*/public void destroy() {// TODO Auto-generated method stub}/*** @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)*/public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("我是MyFilter2开始拦截请求地址");response.setContentType("text/html");response.setCharacterEncoding("UTF-8");chain.doFilter(request, response);}/*** @see Filter#init(FilterConfig)*/public void init(FilterConfig fConfig) throws ServletException {// TODO Auto-generated method stub}}
package com.filter;import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;/*** Servlet Filter implementation class MyFilter3*/
@WebFilter("/Servlet2")
public class MyFilter3 implements Filter {/*** Default constructor. */public MyFilter3() {// TODO Auto-generated constructor stub}/*** @see Filter#destroy()*/public void destroy() {// TODO Auto-generated method stub}/*** @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)*/public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("我是MyFilter3开始拦截请求地址");response.setContentType("text/html");response.setCharacterEncoding("UTF-8");chain.doFilter(request, response);}/*** @see Filter#init(FilterConfig)*/public void init(FilterConfig fConfig) throws ServletException {// TODO Auto-generated method stub}}

 综合案例

我们在浏览器地址上访问Servlet1的时候,携带上两个数据拼接在地址上作为模拟登录功能,

http://localhost:8080/Day10Jsp/Servlet1?name=admin&psd=123456

那么这个请求我们使用MyFilter进行拦截它,获得浏览器想要发给Servlet1的两个数据

package com.filter;import java.io.IOException;
import java.io.OutputStream;import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;public class MyFilter implements Filter {String a="";String b="";public MyFilter() {System.out.println("过滤器开始被创建对象");}@Overridepublic void destroy() {System.out.println("销毁过滤器");}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {response.setContentType("text/html");response.setCharacterEncoding("UTF-8");String name=request.getParameter("name");String psd=request.getParameter("psd");System.out.println("我是MyFilter开始拦截请求地址");}@Overridepublic void init(FilterConfig config) throws ServletException {System.out.println("加载初始化的数据");}}

在过滤器的注册信息中设定两个静态数据

 

在过滤器被加载的时候,将两个静态数据获得出来

@Overridepublic void init(FilterConfig config) throws ServletException {System.out.println("加载初始化的数据");//获得过滤器当中保存的两个正确的静态数据a=config.getInitParameter("username");b=config.getInitParameter("password");}

 然后我们将拦截的浏览器的数据与静态数据进行比较,如果匹配成功,那么运行放行进入Servlet1,如果匹配失败,则不允许进入Servet1

package com.filter;import java.io.IOException;
import java.io.OutputStream;import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;public class MyFilter implements Filter {String a="";String b="";public MyFilter() {System.out.println("过滤器开始被创建对象");}@Overridepublic void destroy() {System.out.println("销毁过滤器");}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {response.setContentType("text/html");response.setCharacterEncoding("UTF-8");String name=request.getParameter("name");String psd=request.getParameter("psd");//拦截到浏览器的用户名和密码需要和过滤器的正确的用户名和密码进行比较//如果验证是正确的,那么放行,否则不允许进入servletif (name.equals(a)&&psd.equals(b)) {//过滤器允许浏览器的请求地址进入servlet   放行chain.doFilter(request, response);}else {OutputStream os=response.getOutputStream();os.write("用户名不存在或者密码错误,属于非法用户,不允许进入服务器".getBytes());}System.out.println("我是MyFilter开始拦截请求地址");}@Overridepublic void init(FilterConfig config) throws ServletException {System.out.println("加载初始化的数据");//获得过滤器当中保存的两个正确的静态数据a=config.getInitParameter("username");b=config.getInitParameter("password");}}

代码的执行效果,初学者自行运行查看!!! 

这篇关于【Jsp】第五课 过滤器的概念与使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/980164

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

【北交大信息所AI-Max2】使用方法

BJTU信息所集群AI_MAX2使用方法 使用的前提是预约到相应的算力卡,拥有登录权限的账号密码,一般为导师组共用一个。 有浏览器、ssh工具就可以。 1.新建集群Terminal 浏览器登陆10.126.62.75 (如果是1集群把75改成66) 交互式开发 执行器选Terminal 密码随便设一个(需记住) 工作空间:私有数据、全部文件 加速器选GeForce_RTX_2080_Ti

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念