java spring 拦截器和过滤器+过滤器处理数据

news2024/10/6 18:35:07

java spring 拦截器和过滤器+过滤器处理数据

  • 介绍
      • Spring拦截器(Interceptor)
        • 导入依赖
        • 完整代码
      • Java过滤器(Filter)
        • 完整代码分为 2 个文件,请看下面
          • BodyReaderHttpServletRequestWrapper.java
          • MyFilter.java
      • Spring过滤器和拦截器的区别

介绍

在Spring框架中,拦截器和过滤器都是用于处理HTTP请求的生命周期中的特定时刻。它们都可以用来拦截请求和响应,并在它们到达目标处理器之前或之后进行一些操作。在本教程中,我们将探讨拦截器和过滤器的区别以及如何使用它们来处理数据。

Spring拦截器(Interceptor)

Spring拦截器是Spring框架特有的,用于在Spring MVC请求处理的前后添加自定义逻辑。拦截器通常用于以下场景:

  • 认证和授权
  • 日志记录
  • 事务管理
  • 请求和响应的修改
    拦截器的工作流程包括:
  • preHandle:在请求处理之前调用,可以用来添加额外的验证或修改请求。
  • postHandle:在请求处理之后,但在视图渲染之前调用,可以用来添加额外的模型数据或修改视图。
  • afterCompletion:在整个请求结束后调用,可以用来进行资源清理。
    拦截器通过Spring的配置文件或注解进行配置。
导入依赖
import org.springframework.stereotype.Component;

导入 Spring的@Component注解,意味着这个类会被Spring的IoC容器自动识别为一个组件,并将其注册到容器中。拦截器实例会随着容器的启动而被创建。

import org.springframework.web.servlet.HandlerInterceptor;

导入了HandlerInterceptor接口,这个接口定义了拦截器的三种方法:preHandle()postHandle()afterCompletion(),该类将实现这些方法。

import org.springframework.web.servlet.ModelAndView;

导入了ModelAndView类,它通常在拦截器的postHandle()方法中被使用,用来访问模型数据和视图信息。

完整代码

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

@Component
public class Interceptor implements HandlerInterceptor {

    /**
     * 拦截器
     *
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        try {

            String requestUrl = httpServletRequest.getRequestURI();
            Map<String, String[]> originRequestMap = httpServletRequest.getParameterMap();

            System.out.println("拦截器执行,参考 class ActionHandle");
        } catch (Exception e) {
        }
        return true;

    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

Java过滤器(Filter)

Java过滤器是Java EE规范的一部分,用于在Servlet容器中处理请求和响应。过滤器通常用于以下场景:

  • 认证和授权
  • 日志记录
  • 事务管理
  • 数据压缩
  • 缓冲区管理
    过滤器的工作流程包括:
  • doFilter:过滤器的核心方法,对请求和响应进行处理。
  • init:在过滤器首次使用前调用,可以用来初始化过滤器。
  • destroy:在过滤器不再使用时调用,可以用来释放资源。
    过滤器通过web.xml配置文件进行配置,或者通过Java配置注解进行配置。
完整代码分为 2 个文件,请看下面
BodyReaderHttpServletRequestWrapper.java
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.net.URLDecoder;
import java.util.*;

public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
    private Map<String, String[]> paramsMap;

    @Override
    public Map getParameterMap() {
        return paramsMap;
    }

    @Override
    public String getParameter(String name) {
        String[] values = paramsMap.get(name);
        if (values == null || values.length == 0) {
            return null;
        }
        return values[0];
    }

    @Override
    public String[] getParameterValues(String name) {
        return paramsMap.get(name);
    }

    @Override
    public Enumeration getParameterNames() {
        return Collections.enumeration(paramsMap.keySet());
    }

    private String getRequestBody(InputStream stream) {
        String line = "";
        StringBuilder body = new StringBuilder();
        int counter = 0;

        // 读取POST提交的数据内容
        BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
        try {
            while ((line = reader.readLine()) != null) {
                if (counter > 0) {
                    body.append("rn");
                }
                body.append(line);
                counter++;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return body.toString();
    }

    private HashMap<String, String[]> getParamMapFromPost(HttpServletRequest request) {

        String body = "";
        try {
            body = getRequestBody(request.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
        HashMap<String, String[]> result = new HashMap<String, String[]>();

        if (null == body || 0 == body.length()) {
            return result;
        }

        return parseQueryString(body);
    }

    // 自定义解码函数
    private String decodeValue(String value) {
        if (value.contains("%u")) {
            return Encodes.urlDecode(value);
        } else {
            try {
                return URLDecoder.decode(value, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                // 非UTF-8编码
                return "";
            }
        }
    }

    public HashMap<String, String[]> parseQueryString(String s) {
        String valArray[] = null;
        if (s == null) {
            throw new IllegalArgumentException();
        }
        HashMap<String, String[]> ht = new HashMap<String, String[]>();
        StringTokenizer st = new StringTokenizer(s, "&");
        while (st.hasMoreTokens()) {
            String pair = (String) st.nextToken();
            int pos = pair.indexOf('=');
            if (pos == -1) {
                continue;
            }
            String key = pair.substring(0, pos);
            String val = pair.substring(pos + 1, pair.length());
            if (ht.containsKey(key)) {
                String oldVals[] = (String[]) ht.get(key);
                valArray = new String[oldVals.length + 1];
                for (int i = 0; i < oldVals.length; i++) {
                    valArray[i] = oldVals[i];
                }
                valArray[oldVals.length] = decodeValue(val);
            } else {
                valArray = new String[1];
                valArray[0] = decodeValue(val);
            }
            ht.put(key, valArray);
        }
        return ht;
    }

    private Map<String, String[]> getParamMapFromGet(HttpServletRequest request) {
        return parseQueryString(request.getQueryString());
    }

    public String getBody() {
        return new String(body);
    }

    // 报文
    private final byte[] body;

    public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        body = readBytes(request.getInputStream());

        //
        /*if ("POST".equals(request.getMethod().toUpperCase())) {
            paramsMap = getParamMapFromPost(this);
        } else {
            paramsMap = getParamMapFromGet(this);
        }*/

    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream bais = new ByteArrayInputStream(body);
        return new ServletInputStream() {

            @Override
            public int read() throws IOException {
                return bais.read();
            }

            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener arg0) {

            }
        };
    }

    private static byte[] readBytes(InputStream in) throws IOException {
        BufferedInputStream bufin = new BufferedInputStream(in);
        int buffSize = 1024;
        ByteArrayOutputStream out = new ByteArrayOutputStream(buffSize);

        byte[] temp = new byte[buffSize];
        int size = 0;
        while ((size = bufin.read(temp)) != -1) {
            out.write(temp, 0, size);
        }
        bufin.close();

        byte[] content = out.toByteArray();
        return content;
    }

}
MyFilter.java

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject; 
import 这里填路径.BodyReaderHttpServletRequestWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.*;

@Component
public class MyFilter implements Filter {

    @Autowired
    public RedisCache redisCache;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    /**
     * 获取配置信息
     */
    public String getSysConfig(String configKey) {
        return redisCache.getCacheObject(CacheConstants.SYS_CONFIG_KEY + configKey);
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        ServletRequest requestWrapper = null;
        String param = "";
        if (request instanceof HttpServletRequest) {
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            String method = httpServletRequest.getMethod().toUpperCase();
            String type = httpServletRequest.getContentType();
            if ("PUT".equals(method) && "application/json;charset=UTF-8".equalsIgnoreCase(type)) {
                requestWrapper = new BodyReaderHttpServletRequestWrapper((HttpServletRequest) request);
            }
        }

        if (requestWrapper == null) {
            Map<String, String[]> originRequestMap = request.getParameterMap();
            Map<String, String> requestMap = new HashMap<String, String>();
            for (String key : originRequestMap.keySet()) {
                String[] values = originRequestMap.get(key);
                requestMap.put(key, values[0]);
            }
            param = JSON.toJSONString(requestMap);
        } else {
            // 获取请求中的流,将取出来的字符串,修改字符串,再次转换成流,然后把它放入到新request对象中
            param = ((BodyReaderHttpServletRequestWrapper) requestWrapper).getBody();
            JSONObject jsonObject = JSONObject.parseObject(param);

            for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                // 这里可以做判断,把参数修改,实现业务
            }
            param = jsonObject.toJSONString();
            // 将修改后的param重新转换为流,放入新的请求对象中
            byte[] bytes = param.getBytes(StandardCharsets.UTF_8);
            ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
            requestWrapper = new HttpServletRequestWrapper((HttpServletRequest) request) {
                @Override
                public ServletInputStream getInputStream() throws IOException {
                    return new CustomServletInputStream(bis);
                }

                @Override
                public BufferedReader getReader() throws IOException {
                    return new BufferedReader(new InputStreamReader(bis));
                }
            };
        }
        System.out.println("过滤器:" + param);
        //放行
        if (requestWrapper == null) {
            chain.doFilter(request, response);
        } else {
            chain.doFilter(requestWrapper, response);
        }
    }

    @Override
    public void destroy() {

    }

    private static class CustomServletInputStream extends ServletInputStream {

        private final ByteArrayInputStream inputStream;

        public CustomServletInputStream(ByteArrayInputStream bis) {
            this.inputStream = bis;
        }

        @Override
        public int read() throws IOException {
            return inputStream.read();
        }

        @Override
        public boolean isFinished() {
            return inputStream.available() == 0;
        }

        @Override
        public boolean isReady() {
            return true; // Always ready to read
        }

        @Override
        public void setReadListener(ReadListener listener) {
            // No async support in this example
        }
    }
}

具体使用的时候参考代码中的注释:“这里可以做判断,把参数修改,实现业务”

这个位置可以通过调试来一步步理解。
在这里插入图片描述

Spring过滤器和拦截器的区别

  • 配置位置
    • 过滤器通常在web.xml中配置。
    • 拦截器可以在Spring的配置文件中配置,也可以使用注解进行配置。
  • 应用范围
    • 过滤器可以应用于Servlet层面的所有请求,不仅限于Spring MVC。
    • 拦截器仅应用于Spring MVC请求。
  • 粒度
    • 过滤器的工作粒度更细,可以处理请求和响应的各个阶段。
    • 拦截器的工作粒度稍粗,主要针对请求的处理流程。
  • 功能
    • 过滤器主要用于通用的事务管理和安全性控制。
    • 拦截器主要用于Spring MVC中的请求处理,如日志记录、权限验证等。

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

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

相关文章

昇思25天学习打卡营第6天|linchenfengxue

​​​​​​SSD目标检测 SSD&#xff0c;全称Single Shot MultiBox Detector&#xff0c;是Wei Liu在ECCV 2016上提出的一种目标检测算法。使用Nvidia Titan X在VOC 2007测试集上&#xff0c;SSD对于输入尺寸300x300的网络&#xff0c;达到74.3%mAP(mean Average Precision)以…

网络编程常见问题

1、TCP状态迁移图 2、TCP三次握手过程 2.1、握手流程 1、TCP服务器进程先创建传输控制块TCB&#xff0c;时刻准备接受客户进程的连接请求&#xff0c;此时服务器就进入了LISTEN&#xff08;监听&#xff09;状态&#xff1b; 2、TCP客户进程也是先创建传输控制块TCB&#xff…

操作系统期末复习考题三(不挂科系列)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、前言&#x1f680;&#x1f680;&#x1f680;二、正文☀️☀️☀️三、总结&#x1f353;&#x1f353;&#x1f353; 一、前言&#x1f680;&#x1f680;&am…

【操作系统期末速成】 EP03 | 学习笔记(基于五道口一只鸭)

文章目录 一、前言&#x1f680;&#x1f680;&#x1f680;二、正文&#xff1a;☀️☀️☀️2.1 考点五&#xff1a;进程的概念及特征2.1 考点六&#xff1a;进程的状态与切换 一、前言&#x1f680;&#x1f680;&#x1f680; ☀️ 回报不在行动之后&#xff0c;回报在行动…

isalnum()方法——判断字符串是否由字母和数字组成

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 语法参考 isalnum()方法用于判断字符串是否由字母和数字组成。isalnum()方法的语法格式如下&#xff1a; str.isalnum() 如果字符串中至少有一个字…

install nebula with source

linux 环境&#xff1a;ubuntu 2004 默认gcc 7.5 nebula requerment&#xff1a; g 8.5 above 下载source git clone --branch release-3.8 https://github.com/vesoft-inc/nebula.git install gcc g 11 apt install gcc-11 g-11 此时 linux环境存在多个版本gcc&#xff1a…

运算放大器(运放)带宽和带宽平坦度

运算放大器带宽和带宽平坦度 电压反馈型运算放大器的带宽 下图1显示电压反馈型运算放大器的开环频率响应。有两种可能&#xff1a;图1A是最常见的情况&#xff0c;高直流增益以6dB/倍频程从极低频率下降至单位增益&#xff0c;也就是典型的单极点响应。相比之下&#xff0c;图…

快速降低地平线4延迟 极限竞速地平线4延迟严重这样做

极限竞速地平线4全新的开放式剧情设计&#xff0c;让玩家的每一次驾驶都充满了未知与挑战。与此同时&#xff0c;现实世界的玩家也将与玩家一同在这片土地上驰骋。在这里&#xff0c;时间、天气和四季的变化都仿佛触手可及&#xff0c;玩家将亲身体验到真实而震撼的赛车世界。在…

使用青否数字人直播软件有哪些优势?

使用青否数字人主播主要具有以下优势&#xff1a; 1、降低直播门槛 在垂直程度较高、专业度更强的行业&#xff0c;面对相关品牌们“专业主播难培养”的问题。数字人主播的学习技能和灵活优势尽显。通过数字人直播可以借助知识库配置与AI能力&#xff0c;快速获得技术性知识&am…

【数据结构|C语言版】四大排序(算法)

前言1. 插入排序1.1 直接插入排序1.2 希尔排序 2. 选择排序2.1 选择排序2.2 堆排序 3. 交换排序3.1 冒泡排序冒泡排序的步骤 3.2 快速排序快速排序的步骤 4. 归并排序归并排序的步骤&#xff1a;代码解释&#xff1a;归并排序的性能&#xff1a; 上期回顾: 【数据结构|C语言版】…

计算几何系列——XCPC中计算几何一些题型杂谈(中)

本系列文章力求以简洁易懂的文字介绍计算几何中的基本概念&#xff0c;使读者快速入门&#xff0c;故不追求难度和深度&#xff0c;仅起到抛砖引玉的作用。 在XCPC中有一种题叫计算几何&#xff0c;这类题在大多数时候都作为一类金牌题甚至防AK题的难度出现&#xff0c;但是在…

3A信用认证的多重作用及其对企业发展的重要意义

在现代商业环境中&#xff0c;企业信用评级已经成为衡量企业信用状况和市场竞争力的重要指标。AA信用认证作为信用评级中的高级别认证&#xff0c;能够为企业带来多方面的积极影响&#xff0c;促进其在市场中的健康发展。本文将详细探讨3A信用认证的多重作用及其对企业发展的重…

鸿蒙开发HarmonyOS NEXT (一) 入门

最近总听见大家讨论鸿蒙&#xff0c;前端转型的好方向&#xff1f;先入门学习下 目前官方版本和文档持续更新中 一、开发环境 提示&#xff1a;要占用的空间比较多&#xff0c;建议安装在剩余空间多的盘 1、下载&#xff1a;官网最新工具 - 下载中心 - 华为开发者联盟 (huaw…

1、项目基础

1、系统架构图 2、项目业务组成 3、技术选型 3.1 前端 vue3 ts sass axios 3.2后端 spring-cloud系列 gateway openfeign spring-cloud-alibaba系列 nacos sentinel seata

【LLM 评估】GLUE benchmark:NLU 的多任务 benchmark

论文&#xff1a;GLUE: A Multi-Task Benchmark and Analysis Platform for Natural Language Understanding ⭐⭐⭐⭐ arXiv:1804.07461, ICLR 2019 Site: https://gluebenchmark.com/ 文章目录 一、论文速读二、GLUE 任务列表2.1 CoLA&#xff08;Corpus of Linguistic Accep…

标准版小程序订单中心path审核不通过处理教程

首先看自己小程序是不是已经审核通过并上线状态才在站内信里面提醒的&#xff1f; 如果没有提交过审核&#xff0c;请在提交的时候填写。path地址为&#xff1a;pages/goods/order_list/index 如果是已经上线的小程序&#xff0c;当时没要求填这个&#xff0c;但新的政策要求填…

查看linux服务磁盘类型

查看linux服务磁盘类型 查看当前服务器磁盘挂载类型 df -h2. 查看/dev/mapper/centos-root挂载卷类型 # 查询 lsblk# 查询磁盘类型 lsblk -d -o name,rota | grep sda # 说明 sda 0 代表固态硬盘ssd sda 1 代表机械硬盘hdd

什么是无头浏览器?

简而言之&#xff0c;无头浏览器是没有图形用户界面 &#xff08;GUI&#xff09; 的 Web 浏览器。GUI 包括用户与之交互的数字元素&#xff0c;例如按钮、图标和窗口。但是&#xff0c;关于无头浏览器&#xff0c;您需要了解的还有很多。 在本文中&#xff0c;您将了解什么是…

实验三 时序逻辑电路实验

仿真 链接&#xff1a;https://pan.baidu.com/s/1z9KFQANyNF5PvUPPYFQ9Ow 提取码&#xff1a;e3md 一、实验目的 1、通过实验&#xff0c;理解触发的概念&#xff0c;理解JK、D等常见触发器的功能&#xff1b; 2、通过实验&#xff0c;加深集成计数器功能的理解&#xff0c;掌…

Python | Leetcode Python题解之第205题同构字符串

题目&#xff1a; 题解&#xff1a; class Solution:def isIsomorphic(self, s: str, t: str) -> bool:dicts Counter(s)dictt Counter(t) if list(dicts.values()) ! list(dictt.values()):return Falsefor i in range(len(s)):inds list(dicts.keys()).index(s…