过滤器的实现及其原理责任链设计模式

Filter过滤器

过滤器的应用

DeptServlet,EmpServlet,OrderServlet三个业务类的业务方法执行之前都需要编写判断用户是否登录和解决的中文乱码的代码,代码没有得到重复利用

Filter是过滤器可以用来编写请求的过滤规则和多个Servlet都会执行的公共代码,Filter中的业务代码既可以在目标Servlet程序执行之前也可以在其之后执行

  • Filter的生命周期和Servlet对象生命周期一致,先实例化(一次即单例)–>执行初始化方法(一次)–>处理请求方法(每次请求都会调用)–>销毁方法(一次)
  • Filter默认情况下在服务器启动阶段就会实例化 , Servlet默认在用户发起对应请求的时候才会实例化
  • Filter的优先级天生的就比Servlet优先级高,若Filter和Servlet都可以处理/a.do请求,那么一定是先执行Filter然后再执行Servlet

在这里插入图片描述

/*** 处理部门相关的业务类*/
@WebServlet({"/dept/list", "/dept/detail", "/dept/delete", "/dept/save", "/dept/modify"})
public class DeptServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 低版本的Tomcat还需要解决post请求乱码问题request.setCharacterEncoding("UTF-8");// 响应中文乱码问题response.setContentType("text/html;charset=UTF-8");// 获取当前session,这个session是不需要新建的,获取不到就返回nullHttpSession session = request.getSession(false);if(session != null && session.getAttribute("username") != null){String servletPath = request.getServletPath();if("/dept/list".equals(servletPath)){doList(request, response);}else if("/dept/detail".equals(servletPath)){doDetail(request, response);}else if("/dept/delete".equals(servletPath)){doDel(request, response);}else if("/dept/save".equals(servletPath)){doSave(request, response);}else if("/dept/modify".equals(servletPath)){doModify(request, response);}}else{// 获取不到session或session中没有存储用户的信息就跳转到登录页面response.sendRedirect(request.getContextPath() + "/index.jsp"); }}
}
/*** 处理员工相关的业务类*/
public class EmpServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 解决post请求乱码问题request.setCharacterEncoding("UTF-8");// 响应中文乱码问题response.setContentType("text/html;charset=UTF-8");HttpSession session = request.getSession(false);if(session != null && session.getAttribute("username") != null){String servletPath = request.getServletPath();//...}else{response.sendRedirect(request.getContextPath() + "/index.jsp");}}
}
/*** 处理订单相关的业务类*/
public class OrderServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 解决post请求乱码问题request.setCharacterEncoding("UTF-8");// 解决响应中文乱码问题response.setContentType("text/html;charset=UTF-8");HttpSession session = request.getSession(false);if(session != null && session.getAttribute("username") != null){String servletPath = request.getServletPath();//...}else{response.sendRedirect(request.getContextPath() + "/index.jsp");}}
}

责任链设计模式

传统模式方法调用时在编译阶段已经完全确定了方法的调用顺序,如果想改变方法的调用顺序必须修改源代码,显然违背了OCP原则

public class Test {public static void main(String[] args) {System.out.println("main begin");m1();System.out.println("main over");}private static void m1() {System.out.println("m1 begin");m2();System.out.println("m1 over");}private static void m2() {System.out.println("m2 begin");m3();System.out.println("m2 over");}private static void m3() {System.out.println("目标正在执行中。。。。");}
}

责任链设计模式: 由于方法的调用顺序在程序编译阶段无法确定,需要根据实际情况在程序运行阶段动态的组合方法的调用顺序,实现代码的灵活性

  • Filter使用了责任链设计模式,将Filter的调用顺序配置到了web.xml文件中,想要调整Filter的执行顺序只需要修改配置文件中filter-mapping标签的顺序
<filter><filter-name>filter</filter-name><filter-class>com.bjpowernode.javaweb.servlet.Filter2</filter-class>
</filter>
<filter-mapping><filter-name>filter</filter-name><url-pattern>*.do</url-pattern>
</filter-mapping>

实现过滤器

第一步:编写一个类实现jarkata.servlet.Filter接口,由于接口中的方法都有默认的方法体,我们可以根据需求实现方法

方法名功能
init(FilterConfig filterConfig)在Filter对象第一次被创建之后调用,并且只调用一次
doFilter(ServletRequest request, ServletResponse response, FilterChain chain)编写过滤规则和公共代码的方法,只要用户发送一次请求就执行一次 , 发送N次请求执行N次
destroy()在Filter对象被释放/销毁之前调用,并且只调用一次

第二步: 执行FilterChain类的doFilter方法放行,过滤器只有放行了请求,目标Servlet才有机会执行到

方法名功能
doFilter(request, response)执行下一个过滤器,如果下面没有过滤器了才执行最终处理对应请求路径的Servlet
public class Filter implements Filter {public Filter1(){System.out.println("无参数构造方法执行");}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("init方法执行。");}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {// 在请求的时候添加过滤规则System.out.println("Filter1 doFilter方法开始执行");// 执行下一个过滤器,如果下一个不是过滤器则执行目标程序Servletchain.doFilter(request, response);// 在响应的时候添加过滤规则System.out.println("Filter1 doFilter方法执行结束");}@Overridepublic void destroy() {System.out.println("destroy方法执行");}
}

第三步: 编写目标Servlet处理用户的请求

@WebServlet("/a.do")
public class AServlet  extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {System.out.println("AServlet中的doGet方法执行了");}
}@WebServlet("/b.do")
public class BServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {System.out.println("BServlet中的doGet方法执行了");}
}

第四步: 配置Filter拦截的请求路径和执行顺序(Filter执行时遵循栈的数据结构),配置过滤器拦截的请求路径时可以使用通配符*

  • 在web.xml文件中配置(常用): Filter的执行顺序取决于filter-mapping标签的配置位置,越靠上优先级越高,和filter标签的位置无关
  • 在@WebFilter注解中配置(修改过滤器执行顺序不方便): Filter的执行顺序取决于Filter的类名(按字典序排序) , 比如在FilterA和FilterB中先执行FilterA
匹配方式举例
精确匹配/a.do、/b.do、/dept/save
模糊匹配*/*表示拦截所有路径
后缀匹配*,不能以/开始*.do表示拦截所有以.do结尾的路径
前缀匹配*,以/开始/dept/*表示拦截/dept/路径及其子路径
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"version="5.0"><filter><filter-name>filter</filter-name><filter-class>com.bjpowernode.javaweb.servlet.Filter</filter-class></filter><filter-mapping><filter-name>filter</filter-name><!--<url-pattern>a.do</url-pattern><url-pattern>b.do</url-pattern>--><url-pattern>*.do</url-pattern></filter-mapping>
</web-app>
//@WebFilter({"/a.do", "/b.do"})
@WebFilter({"*.do"})
public class Filter implements Filter {public Filter1(){System.out.println("无参数构造方法执行");}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("init方法执行。");}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {// 在请求的时候添加过滤规则System.out.println("Filter1 doFilter方法开始执行");// 执行下一个过滤器,如果下一个不是过滤器则执行目标程序Servletchain.doFilter(request, response);// 在响应的时候添加过滤规则System.out.println("Filter1 doFilter方法执行结束");}@Overridepublic void destroy() {System.out.println("destroy方法执行");}
}

使用过滤器改造oa项目

第一步: 编写一个过滤器LoginCheckFilter同时指定不需要拦截的路径

  • 当用户访问index.jsp首页,用户已经登录了(session中有用户信息),用户想要登录或退出,用户访问项目根目录即欢迎页的请求不能拦截
public class LoginCheckFilter implements Filter {@Overridepublic void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {//强制类型转化HttpServletRequest request = (HttpServletRequest)req;HttpServletResponse response = (HttpServletResponse) resp;// 获取请求路径String servletPath = request.getServletPath();HttpSession session = request.getSession(false);if("/index.jsp".equals(servletPath) || "/welcome".equals(servletPath) ||"/user/login".equals(servletPath) || "/user/exit".equals(servletPath)|| (session != null && session.getAttribute("user") != null)){// 继续往下走chain.doFilter(request, response);}else{response.sendRedirect(request.getContextPath() + "/index.jsp");}}
}

第二步: 在web.xml中注册过滤器,/*表示拦截所有的路径

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"version="5.0"><!--登录检查的过滤器,过滤所有的路径--><filter><filter-name>loginFilter</filter-name><filter-class>com.bjpowernode.oa.web.filter.LoginCheckFilter</filter-class></filter><filter-mapping><filter-name>loginFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
</web-app>

第三步: 业务类相关的Servlet就不需要再编写代码判断用户是否登录,如果请求能到目标Servlet说明用户一定是登录过了,目标Servlet只需要转发请求即可

@WebServlet({"/dept/list", "/dept/detail", "/dept/delete", "/dept/save", "/dept/modify"})
public class DeptServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String servletPath = request.getServletPath();if("/dept/list".equals(servletPath)){doList(request, response);}else if("/dept/detail".equals(servletPath)){doDetail(request, response);}else if("/dept/delete".equals(servletPath)){doDel(request, response);}else if("/dept/save".equals(servletPath)){doSave(request, response);}else if("/dept/modify".equals(servletPath)){doModify(request, response);}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/101110.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVM的内存模型

一、JVM的内存模型 1.1、目标 内存模型是用来描述JVM内部的内存结构和内存管理的模型。它定义了JVM在运行Java程序时所需要的各种内存区域&#xff0c;以及每个内存区域的作用和特点。 1.2、结构划分 1.2.1、栈 每个线程在执行Java方法时会创建一个栈帧&#xff08;Stack …

Chrome自动播放限制策略

原文链接&#xff1a;Chrome 自动播放限制策略 Web浏览器正在朝着更严格的自动播放策略发展&#xff0c;以便改善用户体验&#xff0c;最大限度地降低安装广告拦截器的积极性并减少昂贵和/或受限网络上的数据消耗。这些更改旨在为用户提供更大的播放控制权&#xff0c;并使开发…

[sqoop]hive导入mysql,其中mysql的列存在默认值列

一、思路 直接在hive表中去掉有默认值的了列&#xff0c;在sqoop导入时,指定非默认值列即可&#xff0c; 二、具体 mysql的表 hive的表 create table dwd.dwd_hk_rcp_literature(id string,literature_no string,authors string,article_title string,source_title string…

RabbitMQ开启消息发送确认和消费手动确认

开启RabbitMQ的生产者发送消息到RabbitMQ服务端的接收确认&#xff08;ACK&#xff09;和消费者通过手动确认或者丢弃消费的消息。 通过配置 publisher-confirm-type: correlated 和publisher-returns: true开启生产者确认消息。 server:port: 8014spring:rabbitmq:username: …

项目创建 Vue3 + Ts + vite + pinia

vite官网 项目初始化 准备安装工作(按步骤创建) npm init vuelatest创建完成后再次安装对应插件 然后百度配置main.ts里面引入 npm i pinia --save //安装pinia npm i vue-router --save //安装router npm i axios --save //安装axios //安装sass或less npm add -D scss npm…

uniapp-vue3微信小程序实现全局分享

uniapp-vue3微信小程序实现全局分享 文章目录 uniapp-vue3微信小程序实现全局分享微信小程序官方文档的分享说明onShareAppMessage(Object object)onShareTimeline() uniapp 官方文档的分享说明onShareAppMessage(OBJECT) 实现全局分享代码结构如下share.js文件内容main.js注意…

聊聊身边的嵌入式:用了七八年的电动牙刷,突然罢工了!!!

家里用了七八年的电动牙刷&#xff0c;前两天突然罢工。先尝试一下野蛮的修复方法(摔摔打打)&#xff0c;这种独家绝技屡试不爽&#xff0c;曾经修好过收音机&#xff0c;电视机&#xff0c;电子手表… 等等。不过这次&#xff0c;没有成功&#xff01;这周末终于有点儿时间&am…

数据库Mysql三大引擎(InnoDB、MyISAM、 Memory)与逻辑架构

MySQL数据库及其分支版本主要的存储引擎有InnoDB、MyISAM、 Memory等。简单地理解&#xff0c;存储引擎就是指表的类型以及表在计算机上的存储方式。存储引擎的概念是MySQL的特色&#xff0c;使用的是一个可插拔存储引擎架构&#xff0c;能够在运行的时候动态加载或者卸载这些存…

奥威BI系统:做数据可视化大屏,又快又简单

数据可视化大屏的制作难吗&#xff1f;会很花时间精力吗&#xff1f;这就要看用的是什么软件了。如果用的是BI系统&#xff0c;特别是奥威BI系统这类BI商业智能软件&#xff0c;那就是又快又简单。 奥威BI系统介绍&#xff1a; 奥威BI系统是一款高效的数据可视化大屏工具&…

Xilisoft Video Converter Ultimate for Mac:让音视频转换变得更简单

无论是在工作还是娱乐中&#xff0c;我们都会遇到音视频格式不兼容的问题。这时候&#xff0c;一个好用的音视频格式转换工具就显得尤为重要。Xilisoft Video Converter Ultimate for Mac&#xff08;曦力音视频转换&#xff09;就是这样一款让您的音视频转换变得更简单的工具。…

萝卜刀玩具上架亚马逊CPC认证测试标准

含铅或含铅涂料儿童产品的要求 分阶段限制儿童产品所有部件的铅含量&#xff0c;要求在3年内将产品任何可接触部件的铅含量限制从不超过重量的600ppm&#xff08;0.06%&#xff09;降至不超过重量的100ppm&#xff08;0.01%&#xff09;。 铅含量限值&#xff08;总铅含量占重…

Pushgateway的场景使用

1,Pushgateway简介 Pushgateway为Prometheus整体监控方案的功能组件之一,并做为一个独立的工具存在。它主要用于Prometheus无法直接拿到监控指标的场景,如监控源位于防火墙之后,Prometheus无法穿透防火墙;目标服务没有可抓取监控数据的端点等多种情况。在类似场景中,可通…

element树形控件单选

需求功能&#xff1a; 1&#xff0c;element树形控件单选 2&#xff0c;双击节点编辑 <div style"height: calc(100% - 48px)"><el-scrollbar class"scrollbar-wrapper"><el-tree :data"treesObj" show-checkbox default-expan…

stable diffusion艰难炼丹之路

文章目录 概要autoDL系统盘爆满autoDL python3.8切换python3.10dreambooth训练大模型完成后报错 概要 主要是通过autoDL服务器部署stable diffusion&#xff0c;通过dreambooth训练大模型。 问题&#xff1a; autoDL系统盘爆满autoDL python3.8切换python3.10dreambooth训练大…

什么是云计算?云计算简介

其实“云计算”作为一个名词而言&#xff0c;那是相当成功滴。很多人都有听过。但提及云计算”具体是什么?很多人&#xff0c;知其然&#xff0c;却不知其所以然! 利用软件将这些成千上万不可靠的硬件组织成一个稳定可靠的IT系统&#xff0c;以此支撑其公司的IT基础服务。这家…

基于SpringBoot的靓车汽车销售网站

目录 前言 一、技术栈 二、系统功能介绍 用户信息管理 车辆展示管理 车辆品牌管理 用户交流管理 购物车 用户交流 我的订单管理 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的…

vite vue3 pwa 更新提醒

效果 vite-plugin-pwa插件启用pwa后默认会在后台自动更新应用&#xff0c;并在关闭所有已开启的页面并重新打开后激活 通过此方法可以以消息方式提醒用户手动刷新激活更新应用 方法 已经使用vite-plugin-pwa插件启用pwa 修改vite.config.ts export default defineConfig(…

论文阅读——Large Selective Kernel Network for Remote Sensing Object Detection

目录 基本信息标题目前存在的问题改进网络结构另一个写的好的参考 基本信息 期刊CVPR年份2023论文地址https://arxiv.org/pdf/2303.09030.pdf代码地址https://github.com/zcablii/LSKNet 标题 遥感目标检测的大选择核网络 目前存在的问题 相对较少的工作考虑到强大的先验知…

python自动解析301、302重定向链接

嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 &#x1f447; &#x1f447; &#x1f447; 更多精彩机密、教程&#xff0c;尽在下方&#xff0c;赶紧点击了解吧~ python源码、视频教程、插件安装教程、资料我都准备好了&#xff0c;直接在文末名片自取就可 使用模块requ…

8 个 Promise 高级用法

在 js 项目中&#xff0c;promise 的使用应该是必不可少的&#xff0c;但我发现在同事和面试者中&#xff0c;很多中级或以上的前端都还停留在promiseInst.then()、promiseInst.catch()、Promise.all等常规用法&#xff0c;连async/await也只是知其然&#xff0c;而不知其所以然…