系列六、过滤器(二)#案例演示

一、案例演示

说明:如下案例通过springboot的方式演示Filter是如何使用的,以获取Controller中的请求参数为切入点进行演示

1.1、前置准备工作

1.1.1、pom

<dependencies>
	<!-- spring-boot -->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-devtools</artifactId>
		<scope>runtime</scope>
		<optional>true</optional>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
	</dependency>

	<dependency>
		<groupId>org.projectlombok</groupId>
		<artifactId>lombok</artifactId>
		<optional>true</optional>
	</dependency>
	<dependency>
		<groupId>com.alibaba</groupId>
		<artifactId>fastjson</artifactId>
		<version>1.2.76</version>
	</dependency>
</dependencies>

1.1.2、UserDTO

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/4 18:32
 * @Description:
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class UserDTO implements Serializable {

    /**
     * 用户名
     */
    private String username;

    /**
     * 密码
     */
    private String password;

}

1.1.3、StreamUtil

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/5 1:15
 * @Description:
 */
public class StreamUtil {

    public static String getBody(HttpServletRequest request) {
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        InputStream inputStream = null;
        try {
            inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead);
                }
            } else {
                stringBuilder.append("");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return stringBuilder.toString();
    }

    public static ServletInputStream getServletInputStream(byte[] byteArr) {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArr);
        return new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }

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

            @Override
            public void setReadListener(ReadListener readListener) {
            }

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

}

1.1.4、MyHttpServletRequestWrapper

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/4 20:50
 * @Description:
 */
@Getter
@Setter
public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper {

    /**
     * 用于保存读取到的body中的数据
     */
    private String body;


    public MyHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        this.body = StreamUtil.getBody(request);
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        return StreamUtil.getServletInputStream(this.body.getBytes(Charset.forName("UTF-8")));
    }

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

}

1.1.5、LoginService

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/4 23:49
 * @Description:
 */
@Service
public class LoginService {

}

二、创建过滤器

参考:
(1)https://blog.csdn.net/bzu_mei/article/details/126644963
(2)https://blog.csdn.net/worilb/article/details/129616956

2.1、方式一:@WebFilter + @ServletComponentScan

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/4 23:46
 * @Description:
 * @WebFilter(urlPatterns = "/login"):标识在类上,表明这个类是一个过滤器类,当访问 /login 接口时先执行此处的doFilter(执行业务逻辑),
 * 当执行chain.doFilter(wrapper, servletResponse);时,才会真正执行Controller层的代码逻辑
 */
@WebFilter
@Slf4j
public class LoginFilter implements Filter {

	// 实现方法处理逻辑

}
/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/4 23:43
 * @Description:
 *
 * @ServletComponentScan的作用:将标识了@WebServlet、@WebFilter、@WebListener注解标注的类注入到IOC容器中
 */
@ServletComponentScan
@SpringBootApplication
public class SpringbootFilterApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootFilterApplication.class, args);
    }


}

2.2、方式二:FilterRegistrationBean

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/5 1:53
 * @Description:
 *
 */
@Slf4j
public class AuthorityFilter implements Filter {

    // 业务逻辑代码    

}
/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/5 1:59
 * @Description:
 *
 * 注意事项:
 *      此处也可以不写此配置,不写的话,AuthorityFilter由于加了@Component注解,也会被Spring容器管理,但是@Component注解没有路径过滤规则,
 * 即会将所有请求都过滤,配置的意义主要就是为了过滤某一类的请求,如下的配置是只有访问以 /privilege/* 打头的请求才会过滤,访问其他的则不过滤
 */
@Configuration
public class MyFilterConfig {

    @Bean
    public FilterRegistrationBean registrationBean() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new AuthorityFilter());
        registrationBean.setName("authorityFilter");
        registrationBean.addUrlPatterns("/privilege/*");
        registrationBean.setOrder(1);

        return registrationBean;
    }

}

三、使用过滤器(案例)

3.1、获取Controller层@RequestBody中的对象参数

3.1.1、LoginController#login()

@PostMapping("/login")
public String login(@RequestBody UserDTO param) {
    log.info("LoginController login param : {}", param);
    return "OK";
}

3.1.2、LoginFilter#doFilter()

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
	log.info("==================== LoginFilter doFilter ====================");
	log.info("bean loginService exist result : {} 存在", loginService == null ? "不" : "");

	HttpServletRequest request = (HttpServletRequest) servletRequest;
	MyHttpServletRequestWrapper wrapper = new MyHttpServletRequestWrapper(request);
	String jsonParam = wrapper.getBody();
	log.info("jsonParam:{}", jsonParam);

	chain.doFilter(wrapper, servletResponse);
}

3.1.3、测试

3.2、获取Controller层普通的对象参数

3.2.1、LoginController#login2()

@PostMapping("/login2")
public String login2(UserDTO param) {
    log.info("LoginController login2 param : {}", param);
    return "OK";
}

3.2.2、LoginFilter#doFilter()

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
    log.info("==================== LoginFilter doFilter ====================");
    log.info("bean loginService exist result : {} 存在", loginService == null ? "不" : "");
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    Map<String, String[]> parameterMap = request.getParameterMap();
    Map<String, Object> requestMap = new HashMap<>();
    for (String key : parameterMap.keySet()) {
        String[] values = parameterMap.get(key);
        requestMap.put(key,values[0]);
    }
    log.info("requestMap:{}",requestMap);
    chain.doFilter(servletRequest, servletResponse);
}

3.2.3、测试#form-data

3.2.4、测试#x-www-form-urlencoded

3.3、获取Controller层字符串参数

3.3.1、LoginController#login3()

@GetMapping("/login3")
public String login3(String username, String password) {
    log.info("LoginController login3 username:{},password:{}", username, password);
    return "OK";
}

3.3.2、LoginFilter#doFilter()

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
    log.info("==================== LoginFilter doFilter ====================");
    log.info("bean loginService exist result : {} 存在", loginService == null ? "不" : "");
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    Map<String, Object> paramMap = new HashMap<>(2);
    paramMap.put("username", username);
    paramMap.put("password", password);
    log.info("paramMap:{}", paramMap);
    chain.doFilter(servletRequest, servletResponse);
}

3.3.3、测试

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

tcp/ip协议2实现的插图,数据结构2 (15 - 章)

(40) 40 十五1 插口层 结构socket,sysent (41) 41 十五2 插口层 实用函数与file结构描述汇总 (42) 42 十五3 插口层 函socket,socreate,pr_usrreq (43)

java毕业设计基于springboot+vue线上教学辅助系统

项目介绍 本论文主要论述了如何使用JAVA语言开发一个线上教学辅助系统 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述线上教学辅助系统的当前背景以及系统开…

【Python基础】Python编程入门自学笔记,基础大全,一篇到底!

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

基于Qt命令行处理XML文件读写

Qt源码在后面,文本介绍Qt国际化语言和XML # XML基础(一) ## 1、概述 ### 1.1 定义(xml是个啥玩意儿?) XML(extensible Markup Language)俗称差妹儿,专业称之为:可拓展标记语言。 (1)何为标记,指的是一种标记语言,或者标签语言,即用一系列的标签来对数据进行…

SSD入门到精通系列-总目录

依公知及经验整理&#xff0c;原创保护&#xff0c;禁止转载。 专栏 《SSD入门到精通系列》 综述&#xff1a; SSD-序 [SSD综述1.1] 导论 [SSD综述1.2] SSD 和 HDD&#xff08;机械硬盘) 区别&#xff1f; 免责声明&#xff1a; 本文根据公开信息整理&#xff0c;旨在介绍更…

layui form 中input输入框长度的统一设置

Layui.form中使用class"layui-input-inline"就可轻松将元素都放到一行&#xff0c;但如果元素过多&#xff0c;就会自动换行。那就需要手动设置input框的长度。 像这种情况&#xff1a; 其实只需要添加css样式就可修改了 .layui-form-item .layui-input-inline {wid…

【牛客网】安全—加密和安全

每日一练 Day1&#xff1a; 1.信息安全的基本属性是&#xff08; D &#xff09; A.保密性 B.完整性 C.可用性&#xff0c;可靠性&#xff0c;可控性 D.A、B、C都是 信息安全的基本属性通常可以归纳为以下几个方面&#xff1a; 保密性&#xff08;Confidentiality&#xf…

Linux学习第28天:Platform设备驱动开发(二): 专注与分散

Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 三、硬件原理图分析 四、驱动开发 1、platform设备与驱动程序开发 53 /* 54 * 设备资源信息&#xff0c;也就是 LED0 所使用的所有寄存器 55 */ 56 static str…

自定义SpringBoot启动图标

在SpringBoot项目的resources目录下创建banner.txt文件 在https://www.bootschool.net/网站上复制Ascll艺术字&#xff08;图&#xff09;粘贴到banner.txt中保存。 启动项目就会加载 可以修改颜色&#xff0c;和版本号 ${application.version} 输出版本 ${spring-boot.v…

计网note

其他 未分类文档 CDMA是码分多路复用技术 和CMSA不是一个东西 UPD是只确保发送 但是接收端收到之后(使用检验和校验 除了检验的部分相加 对比检验和是否相等。如果不相同就丢弃。 复用和分用是发生在上层和下层的问题。通过比如时分多路复用 频分多路复用等。TCP IP 应用层的…

uni-app华为审核被拒,驳回原因:您的应用在运行时,未见向用户告知权限申请的目的

华为审核被拒&#xff1a; 您的应用在运行时&#xff0c;未见向用户告知权限申请的目的&#xff0c;向用户索取(相机存)等权限&#xff0c;不符合华为应用市场审核标准。 <uni-popup ref"perpopup" type"center" :mask-clickfalse><view class&qu…

【解锁未来】探索Web3的无限可能-02

文章目录 什么是Web3 &#xff1f;Web3对公司的意义&#xff1f; 什么是Web3 &#xff1f; 简单地说&#xff0c;Web3 是加密货币的延伸&#xff0c;它以新的方式使用区块链来达到新的目的。区块链可以存储钱包中代币的数量、自我执行合同的条款或去中心化应用程序&#xff08;…

《申论技巧》

一、做题过程 做题过程&#xff1a; 四个要素分析题干 一对多&#xff1a;考虑材料之间的灵活运用&#xff1b;问题对策&#xff1b;并列&#xff1b;主材料与辅材料 多个题目对应一个一篇材料&#xff1b;答案各有侧重&#xff0c;不重合 主体内容 二、读材料 2.1 粗读…

2023辽宁省数学建模A题铁路车站的安全标线完整原创论文详细讲解(含matlab代码)

大家好呀&#xff0c;从发布赛题一直到现在&#xff0c;总算完成了辽宁省数学建模A题完整的成品论文。 本论文可以保证原创&#xff0c;保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半成品论文。 B预计下午两点前更新完毕&#xff0c;A全…

手写数字识别--神经网络实验

实验源码自取&#xff1a; 我自己搞的代码&#xff0c;预测精度才94% 神经网络实验报告源码.zip - 蓝奏云 老师给的实验源码答案和资料&#xff0c;预测精度高达99% 深度学习实验报告.zip - 蓝奏云 上深度学习的课程&#xff0c;老师布置了一个经典的实验报告&#xff0c;我做…

“凸函数”是什么?

凸函数&#xff08;英文&#xff1a;Convex function&#xff09;是指函数图形上&#xff0c;任意两点连成的线段&#xff0c;皆位于图形的上方&#xff0c;如单变数的二次函数和指数函数。二阶可导的一元函数为凸&#xff0c;当且仅当其定义域为凸集&#xff0c;且函数的二阶导…

Nginx搭配负载均衡和动静分离:构建高性能Web应用的完美组合

目录 前言 一、Nginx简介 1.Nginx是什么 2.Nginx的特点 3.Nginx在哪使用 4.如何使用Nginx 5.Nginx的优缺点 6.Nginx的应用场景 二、负载均衡和动静分离 1.负载均衡 2.动静分离 三、Nginx搭载负载均衡并提供前后端分离后台接口数据 1.Nginx安装 2.tomcat负载均衡 …

安装anaconda时控制台conda-version报错

今天根据站内的一篇博客教程博客在此安装anaconda时&#xff0c;检查conda版本时报错如下&#xff1a; >>>>>>>>>>>> ERROR REPORT <<<<<<<<<<<< Traceback (most recent call last): File “D:\An…

Java自学第1课:安装JDK+Eclipse

1 引言 在学习前&#xff0c;我想说一句&#xff0c;那就是为什么要学习Java。 每个人的出发点都不同&#xff0c;对于做信息化的工程技术人员来说&#xff0c;java不懂&#xff0c;就没法干项目。 尽管有c和matlab等基础&#xff0c;但java看起来与这些语言都不太一样。 做…

自定义类型联合体

目录 联合体联合体类型的声明联合体的特点相同成员的结构体和联合体对比联合体大小的计算联合体的应用联合的一个练习 感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接 &#x1f412;&#x1f412;&#x1f412; 个人主页 &#x1f978;&#x1f978;&#x1f…