filter功能演示-鉴权、声明缓存

news2024/12/24 21:14:08

文章目录

  • Filter定义
    • 工作原理
    • Filter所处环节
  • Demo示例
  • 总结

Filter定义

在Java EE(Java Platform, Enterprise Edition)中,过滤器(Filter)是一种强大的组件,用于在Web应用程序中拦截和处理传入的请求和响应。过滤器可以在请求进入Web应用程序之前进行预处理,也可以在响应离开Web应用程序之前进行后处理。通过使用过滤器,我们可以实现许多功能,包括鉴权、声明缓存、日志记录、字符编码转换等。

工作原理

过滤器在Java EE中的工作原理如下:

  1. 过滤器被注册到Web应用程序的部署描述符(web.xml)中或通过使用注解@WebFilter进行标记。可以通过配置过滤器的URL模式,指定哪些URL需要被过滤器拦截。

  2. 当一个客户端发送一个请求到Web应用程序时,过滤器会拦截该请求。过滤器可以在请求进入Web应用程序之前进行预处理,也可以在响应离开Web应用程序之前进行后处理。

  3. 过滤器链(Filter Chain)允许我们定义多个过滤器,并按照指定的顺序依次执行它们。过滤器链保证了过滤器按照预期的顺序执行,每个过滤器都可以对请求进行处理,并将请求传递给下一个过滤器或Web资源。

  4. 过滤器可以对请求进行修改、验证和验证,并在需要时终止请求处理或重定向到其他资源。

  5. 过滤器还可以对响应进行修改,例如添加响应头、修改响应内容等。

Filter所处环节

在这里插入图片描述
当一个完整的Web请求进入Java EE应用程序时,以下是图示中各个部分的解释:

  1. Web客户端:代表发起请求的用户浏览器或其他Web客户端。

  2. Java EE容器:表示Java EE应用程序的运行时环境,包含一系列的服务和功能,用于管理和执行Java EE应用程序的组件。在容器内部,请求经过处理并相应地路由到相应的组件。

  3. 过滤器链:由一系列过滤器组成的链路,每个过滤器都可以在请求进入Servlet之前或响应返回给客户端之前对其进行处理。过滤器可以执行各种任务,如鉴权、日志记录、数据验证等。

  4. Servlet处理器:是Java EE应用程序中处理请求和生成响应的主要组件。它根据请求的URL和其他标识符来调用适当的Servlet,并将请求转发给它。Servlet执行业务逻辑、访问数据库或其他后端服务,并生成相应的响应。

  5. 视图组件:这里表示处理视图层的组件,例如JSP(JavaServer Pages)、JSF(JavaServer Faces)等。它们负责生成动态页面或其他形式的用户界面,将业务逻辑和数据呈现给用户。

  6. 数据库或其他后端服务:表示与Java EE应用程序交互的后端服务,例如数据库服务器、消息队列、外部API等。Java EE应用程序可以通过适当的API与这些服务进行交互,以访问和操作数据。

  7. 返回响应:表示生成的响应从Java EE容器返回给客户端。响应可以包含HTML、JSON、XML或其他形式的数据,根据请求的处理结果来提供相应的内容。

整个流程中,Web客户端发起请求,并通过Java EE容器进行处理。过滤器链在请求到达Servlet之前和响应返回给客户端之前对其进行干预和处理。Servlet处理器执行业务逻辑,并将生成的响应返回给客户端。视图组件用于生成用户界面,而数据库或其他后端服务提供数据存储和其他支持。

Demo示例

当涉及到Web应用程序的鉴权和声明缓存时,使用Java EE规范中的过滤器功能是一种常见的做法。过滤器可以拦截传入的请求,并在处理请求之前进行鉴权验证和声明缓存。本文将演示如何使用Java EE规范的过滤器功能来实现鉴权和声明缓存的功能。

首先,我们需要创建一个过滤器类,并在该类上使用@WebFilter注解来指定要拦截的URL路径。以下是一个示例代码:

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebFilter(urlPatterns = "/*")
public class AuthCacheFilter implements Filter {

    // 模拟用户数据,实际应用中通常是从数据库或其他存储中获取
    private static Map<String, UserData> userMap = new HashMap<>();

    static {
        userMap.put("admin", new UserData("admin123", null));
        userMap.put("user", new UserData("user123", null));
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;

        String token = request.getHeader("Authorization");

        // 检查是否存在令牌
        if (token == null || token.isEmpty()) {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Missing token");
            return;
        }

        // 检查令牌是否有效
        String username = null;
        for (Map.Entry<String, UserData> entry : userMap.entrySet()) {
            UserData userData = entry.getValue();
            if (token.equals(userData.getToken())) {
                username = entry.getKey();
                break;
            }
        }

        if (username == null) {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid token");
            return;
        }

        // 将用户名添加到请求属性中,以便后续使用
        request.setAttribute("username", username);

        // 继续处理请求
        chain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig config) throws ServletException {
        // 初始化过滤器
    }

    @Override
    public void destroy() {
        // 销毁过滤器
    }

    // 模拟用户数据类
    private static class UserData {
        private String password;
        private String token;

        public UserData(String password, String token) {
            this.password = password;
            this.token = token;
        }

        public String getPassword() {
            return password;
        }

        public String getToken() {
            return token;
        }

        public void setToken(String token) {
            this.token = token;
        }
    }
}

在上述代码中,我们首先定义了一个AuthCacheFilter类,并使用@WebFilter注解将其标记为一个过滤器,并指定要拦截的URL路径(在本例中为"/*",即拦截所有请求)。

doFilter方法中,我们首先将ServletRequestServletResponse对象转换为HttpServletRequestHttpServletResponse对象

,以便能够使用HTTP特定的方法和功能。

接下来,我们从请求头中获取授权令牌,并进行鉴权验证。如果令牌为空或不存在,我们将返回一个未经授权的错误响应。如果令牌有效,则将其与模拟的用户数据进行比对,以查找匹配的用户名。

如果找到了匹配的用户名,则将其添加到请求属性中,以便后续处理使用。然后,我们调用chain.doFilter方法,继续处理请求。

在过滤器类的末尾,我们定义了一个内部静态类UserData,用于模拟用户数据。在实际应用中,您可以将此部分替换为从数据库或其他存储中获取真实用户数据的逻辑。

通过使用这个过滤器类,我们可以轻松地实现鉴权和声明缓存的功能。要添加更多的功能,例如声明缓存,您可以在doFilter方法中根据需要添加逻辑。例如,您可以将声明缓存存储在UserData对象中,并在需要时从中检索出来。

此外,您还可以通过使用过滤器链(Filter Chain)来应用多个过滤器,并按照特定顺序对请求进行处理。这使得我们可以将鉴权过滤器与其他过滤器(如日志记录、数据验证等)组合在一起,以构建更复杂的Web应用程序功能。

总结起来,通过使用Java EE规范的过滤器功能,我们可以轻松实现鉴权和声明缓存的功能,并将其应用于Web应用程序中。这提供了一种灵活且可扩展的方法来处理请求,并根据需要执行各种处理逻辑。

请注意,本文中的代码示例只是一个基本的起点,您可以根据自己的需求和具体场景进行修改和扩展。在实际应用中,您可能需要考虑更复杂的鉴权机制、声明缓存策略等方面的实现细节。

总结

在本文中,我们通过使用Java EE规范的过滤器功能,演示了如何实现鉴权和声明缓存的功能。下面是对本文内容的总结:

  1. 过滤器是Java EE规范中的一种功能强大的组件,用于拦截和处理传入的请求。
  2. 通过使用@WebFilter注解,我们可以将过滤器应用于指定的URL路径。
  3. 在本示例中,我们创建了一个名为AuthCacheFilter的过滤器类,并将其应用于所有URL。
  4. 在过滤器的doFilter方法中,我们首先将请求和响应对象转换为HttpServletRequestHttpServletResponse,以便能够使用HTTP特定的功能。
  5. 我们从请求头中获取授权令牌,并进行鉴权验证。
  6. 如果令牌为空或无效,我们返回相应的错误响应。
  7. 如果令牌有效,我们将其与模拟的用户数据进行比对,以查找匹配的用户名。
  8. 如果找到匹配的用户名,我们将其添加到请求属性中,以便后续处理使用。
  9. 最后,我们调用chain.doFilter方法,继续处理请求。
  10. 此外,我们还模拟了一个简单的用户数据类,以存储用户信息和令牌。
  11. 在实际应用中,您可以将用户数据存储在数据库或其他存储中,并根据需要进行检索和验证。
  12. 使用过滤器链(Filter Chain),我们可以应用多个过滤器,并按特定顺序处理请求,以构建更复杂的Web应用程序功能。
  13. 鉴权和声明缓存只是过滤器功能的一个示例,您可以根据自己的需求和具体场景进行修改和扩展。
  14. 过滤器功能提供了一种灵活且可扩展的方式来处理请求,并根据需要执行各种处理逻辑。

总的来说,使用Java EE规范的过滤器功能可以帮助我们实现鉴权和声明缓存等功能。通过适当的配置和编写过滤器代码,我们可以确保只有经过授权的用户能够访问受保护的资源,并且可以提高应用程序的性能和效率,通过缓存声明数据来减少不必要的重复计算或请求。

希望本文能够为您提供一个良好的起点,帮助您理解和使用过滤器功能来实现鉴权和声明缓存。如有需要,请根据自己的需求对示例代码进行修改和扩展,以适应您的具体场景。

					🌈此文章对你有用的话记得留言+点赞+收藏哦🌈

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

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

相关文章

银河麒麟服务器V10 SP1 .Net6.0 开机自启动

开机自动启动&#xff0c;折腾了一小天&#xff0c;设置/etc/init.d/ 、update-rc.d&#xff0c;可能刚开始用&#xff0c;经验不多吧&#xff0c;尝试多种方式我的服务怎么都启动不起来&#xff0c;根据之前nginx和redis的自动启动经验&#xff0c;使用systemd管理服务&#x…

Unity基础 物理系统 刚体组件下的移动.碰撞.触发检测

当在Unity中创建游戏或应用程序时&#xff0c;重力系统是一个非常重要的组成部分。它可以模拟物体受到地球引力的影响&#xff0c;并产生逼真的物理效果。在Unity中&#xff0c;我们可以使用刚体组件和重力向量来控制重力系统。 首先&#xff0c;在Unity中创建一个物体&#xf…

数据表示与数据编码

数据表示与数据编码 数据表示 bit:二进制位 例如:480Mbps(Mb/s) 小写字母b代表bitbyte:字节 1byte8bit 使用大写字母B表示 byte最初从IBM360中开始表示word:字长 在32bit计算机中一个字长为32位&#xff0c;在64bit计算机中一个字长为64位 最早的微处理器字长为4位 章节学习内…

Windows的基本操作

Windows的基本操作 一、用户管理1.1、用户帐户1.2、用户管理 二、网络配置2.1、配置和查看命令 三、常用命令 一、用户管理 1.1、用户帐户 系统中的一种对象&#xff08;用户、组、计算机&#xff09;包含多种属性&#xff0c;如用户名、密码等不同用户帐户的用户名和密码等一…

插入排序--直接插入排序,折半插入排序,希尔排序

插入排序是一种简单直观的排序方法&#xff0c;其基本思想是每次将一个待排序的记录按其关键词大小插入前面已经排好的子序列&#xff0c;直到全部记录插入完成。 一&#xff0c;直接插入排序&#xff1a;从小到大排序 数组序号01234567待排序列4938659776132749第一轮384965…

【数据算法与结构】用按层次顺序遍历二叉树的方法,统计树中具有度为1的结点数目

题目&#xff1a; Qestion: 用按层次顺序遍历二叉树的方法&#xff0c;统计树中具有度为1的结点数目。 数据结构定义 typedef struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right; } TreeNode;样例二叉树的形状 核心代码 // 统计具有度为1的节点数目的…

解决idea默认配置maven仓库地址的问题

我的maven配置地址 一直没注意 jar包什么的全部都是C盘默认的路径&#xff0c;导入项目更改后&#xff0c;再次导入项目 路径还是会变成C盘的路径&#xff1b; 上网搜索找到了解决的办法&#xff1b; 一、File——>New Projects Setup ———>Settings for New Projects…

React hooks之useCallback的使用与性能分析

使用useCallback优化代码 useCallback是对传过来的回调函数优化&#xff0c;返回的是一个函数&#xff1b;useMemo返回值可以是任何&#xff0c;函数&#xff0c;对象等都可以。 简单来说就是返回一个函数&#xff0c;只有在依赖项发生变化的时候才会更新&#xff08;返回一个…

vue项目打包后如何本都部署访问

npm run build生成dist项目后&#xff0c;在windows部署访问。 方式一&#xff1a; 1、新建一个文件夹 进入目录后打开cmd 输入npm init -y 2、输入 npm i express -s 是用于在 Node.js 项目中安装 Express 框架的命令 3、.将项目打包好的dist文件放入其中以及新建一个app.js文…

C++ 二叉搜索树

1. 内容安排说明 二叉树在前面 C 数据结构阶段已经讲过&#xff0c;本节取名二叉树进阶是因为&#xff1a; 1. map 和 set 特性需要 先铺垫二叉搜索树&#xff0c;而二叉搜索树也是一种树形结构 2. 二叉搜索树的特性了解&#xff0c;有助于更好的理解 map 和 set 的特性 …

在JDK17尝鲜Flink1.17

在JDK17尝鲜Flink1.17 前言 还没玩明白老版本&#xff0c;Flink1.17就来了&#xff01;&#xff01;&#xff01;总还是要向前看的。。。 根据官网文档&#xff1a;https://nightlies.apache.org/flink/flink-docs-release-1.17/docs/try-flink/local_installation/ Flink r…

【Excel技巧】如何将一堆文字快速整理成一列表格数据?

在平时的工作中&#xff0c;我们有时候需要把很多零散的分布的内容&#xff08;比如姓名&#xff09;&#xff0c;复制到Excel工作表的单元格内&#xff0c;变成一列。如果一个个复制粘贴&#xff0c;显然太过繁琐。 如何批量快速的完成这一操作呢&#xff1f;只需要下面简单几…

关于排查springboot启动时页面出现404

今天在进行开发时&#xff0c;Contronller代码没有问题&#xff0c;前端html也没问题&#xff0c;发现当浏览器输入localhost:8080时404&#xff0c;于是进行排查发现&#xff0c;SpringbootWebApplication文件放到了子目录下。 springboot的启动文件必须放在父目录下才可以检测…

【Git原理与使用】-- 远程操作

目录​​​​​​​ 理解分布式版本控制系统 远程仓库 新建远程仓库 lssue 与 Pull Request模板文件 知识铺垫 lssue 模板文件 Pull Request模板文件 克隆远程仓库 使用 HTTPS 方式 使用 SSH 方式 第一步&#xff1a;创建SSH Key 向远程仓库推送 过程梳理 实操 …

Java安全——安全提供者

Java安全 安全提供者 在Java中&#xff0c;安全提供者&#xff08;Security Provider&#xff09;是一种实现了特定安全服务的软件模块。它提供了一系列的加密、解密、签名、验证和随机数生成等安全功能。安全提供者基础设施在Java中的作用是为开发人员提供一种扩展和替换标准…

vue中使用Drawflow连线插件,并对端口进行命名

效果如图 场景:项目中需要拖拽模块并连线,有输入端和输出端之分,不同模块不同端口才能相连 文档相关 点击前往------->原项目git地址 点击前往------->提供端口既可输出又可输出方案 点击前往----->查阅发现原项目无法对端口命名 public文件夹下创建drawflow文件夹…

myCobot 280 2023机械臂全新功能,手柄控制、自干涉检测

引言 机械臂是一种可编程的、自动化的机械系统&#xff0c;它可以模拟人类的动作&#xff0c;完成各种任务&#xff0c;例如装配、喷涂、包装、搬运、焊接、研磨等。由于其高度灵活性和多功能性&#xff0c;机械臂在现代社会中已经得到了广泛的应用。 myCobot 280 M5Stack 20…

在服务器部署前后端分离的项目(前后都有), 并使用nginx配置跨域

怎样部署自己的项目呢 先准备一个服务器(小系统最便宜的轻量级服务器就行, 如果不需要给人访问的话)安装宝塔面板 (宝塔面板, 可视化界面, 操作简单, 使用非常方便, 上手也很容易, 如果只是学习, 虚拟机也行没必要花钱, 我使用的CentOS7系统,安装宝塔面板)软件: MySQL, Tomcat…

【问题记录】多线程环境下,使用 std::cout 输出内容会显示混乱

环境 Windows 11 家庭中文版Microsoft Visual Studio Community 2022 (64 位) - Current 版本 17.5.3 测试代码 #include <iostream> #include <Windows.h>//创建的线程数量 #define THREAD_COUNT 4DWORD WINAPI ThreadProc(LPVOID lpParam) {UNREFERENCED_P…

JS事件监听

目录 事件监听 事件监听案例 事件监听 事件&#xff1a;HTML事件是发生在HTML元素上的“事情” 按钮点击鼠标移动到元素上按下键盘按键事件监听&#xff1a;JS可以在事件被检测到时执行代码事件绑定 方法一&#xff1a;通过HTML标签中的事件属性进行绑定 <input type"…