系列十一、拦截器(二)#案例演示

一、案例演示

说明:如下案例通过springboot的方式演示拦截器是如何使用的,以获取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><dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils</artifactId><version>1.9.3</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.6</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.4</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId><version>4.3</version></dependency><!-- servlet --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency></dependencies>

1.1.2、WebRequestConstant

/*** @Author : 一叶浮萍归大海* @Date: 2023/11/5 11:39* @Description:*/
public class WebRequestConstant {/*** 请求方法:POST*/public static final String METHOD_TYPE_POST = "POST";/*** 数据类型:application/json*/public static final String CONTENT_TYPE_APPLICATION_JSON = "application/json";/*** 字符解码*/public static final String CHARACTER_U = "%u";}

1.1.3、EncodeUtil 

/*** @Author : 一叶浮萍归大海* @Date: 2023/11/5 11:12* @Description:*/
public class EncodeUtil {private static final String DEFAULT_URL_ENCODING = "UTF-8";private static final char[] BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();/*** Hex编码.*/public static String encodeHex(byte[] input) {return Hex.encodeHexString(input);}/*** Hex解码.*/public static byte[] decodeHex(String input) {try {return Hex.decodeHex(input.toCharArray());} catch (DecoderException e) {return null;}}/*** Base64编码.*/public static String encodeBase64(byte[] input) {return Base64.encodeBase64String(input);}/*** Base64编码, URL安全(将Base64中的URL非法字符'+'和'/'转为'-'和'_', 见RFC3548).*/public static String encodeUrlSafeBase64(byte[] input) {return Base64.encodeBase64URLSafeString(input);}/*** Base64解码.*/public static byte[] decodeBase64(String input) {return Base64.decodeBase64(input);}/*** Base62编码。*/public static String encodeBase62(byte[] input) {char[] chars = new char[input.length];for (int i = 0; i < input.length; i++) {chars[i] = BASE62[(input[i] & 0xFF) % BASE62.length];}return new String(chars);}/*** Html 转码.*/public static String escapeHtml(String html) {return StringEscapeUtils.escapeHtml4(html);}/*** Html 解码.*/public static String unescapeHtml(String htmlEscaped) {return StringEscapeUtils.unescapeHtml4(htmlEscaped);}/*** Xml 转码.*/public static String escapeXml(String xml) {return StringEscapeUtils.escapeXml(xml);}/*** Xml 解码.*/public static String unescapeXml(String xmlEscaped) {return StringEscapeUtils.unescapeXml(xmlEscaped);}/*** URL 编码, Encode默认为UTF-8.*/public static String urlEncode(String part) {try {return URLEncoder.encode(part, DEFAULT_URL_ENCODING);} catch (UnsupportedEncodingException e) {e.printStackTrace();return null;}}/*** URL 解码, Encode默认为UTF-8.*/public static String urlDecode(String part) {try {return URLDecoder.decode(part, DEFAULT_URL_ENCODING);} catch (UnsupportedEncodingException e) {e.printStackTrace();return null;}}
}

1.1.4、StreamUtil

/*** @Author : 一叶浮萍归大海* @Date: 2023/11/5 1:15* @Description:*/
public class StreamUtil {public static String getRequestBody(InputStream inputStream) {String line = "";StringBuilder body = new StringBuilder();int counter = 0;// 读取POST提交的数据内容BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));try {while ((line = reader.readLine()) != null) {if (counter > 0) {body.append("rn");}body.append(line);counter++;}} catch (IOException e) {e.printStackTrace();}return body.toString();}public static HashMap<String, String[]> parseQueryString(String source) {String[] valueArray = null;if (source == null) {throw new IllegalArgumentException();}HashMap<String, String[]> hashMap = new HashMap<String, String[]>(16);StringTokenizer st = new StringTokenizer(source, "&");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 (hashMap.containsKey(key)) {String[] oldValues = (String[]) hashMap.get(key);valueArray = new String[oldValues.length + 1];for (int i = 0; i < oldValues.length; i++) {valueArray[i] = oldValues[i];}valueArray[oldValues.length] = decodeValue(val);} else {valueArray = new String[1];valueArray[0] = decodeValue(val);}hashMap.put(key, valueArray);}return hashMap;}/*** 自定义解码函数** @param value* @return*/private static String decodeValue(String value) {if (value.contains(WebRequestConstant.CHARACTER_U)) {return EncodeUtil.urlDecode(value);} else {try {return URLDecoder.decode(value, "UTF-8");} catch (UnsupportedEncodingException e) {// 非UTF-8编码return "";}}}public static ServletInputStream getServletInputStream(ByteArrayInputStream bais) {return new ServletInputStream() {@Overridepublic int read() throws IOException {return bais.read();}@Overridepublic boolean isFinished() {return false;}@Overridepublic boolean isReady() {return false;}@Overridepublic void setReadListener(ReadListener arg0) {}};}public 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;}}

1.1.5、MyHttpServletRequestWrapper

/*** @Author : 一叶浮萍归大海* @Date: 2023/11/4 20:50* @Description:*/
@Getter
@Setter
public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper {/*** 用于保存读取到的body中的数据*/private byte[] body;private Map<String, String[]> paramsMap;@Overridepublic Map getParameterMap() {return paramsMap;}@Overridepublic String getParameter(String name) {String[] values = paramsMap.get(name);if (values == null || values.length == 0) {return null;}return values[0];}@Overridepublic String[] getParameterValues(String name) {return paramsMap.get(name);}@Overridepublic Enumeration getParameterNames() {return Collections.enumeration(paramsMap.keySet());}private HashMap<String, String[]> getParamMapFromPost(HttpServletRequest request) {String body = "";try {body = StreamUtil.getRequestBody(request.getInputStream());} catch (IOException e) {e.printStackTrace();}HashMap<String, String[]> result = new HashMap<String, String[]>(16);if (null == body || 0 == body.length()) {return result;}return StreamUtil.parseQueryString(body);}private Map<String, String[]> getParamMapFromGet(HttpServletRequest request) {return StreamUtil.parseQueryString(request.getQueryString());}public String getBody(){return new String(body);}public MyHttpServletRequestWrapper(HttpServletRequest request) throws Exception {super(request);body = StreamUtil.readBytes(request.getInputStream());}@Overridepublic BufferedReader getReader() throws IOException {return new BufferedReader(new InputStreamReader(getInputStream()));}@Overridepublic ServletInputStream getInputStream() throws IOException {final ByteArrayInputStream bais = new ByteArrayInputStream(body);return StreamUtil.getServletInputStream(bais);}}

1.1.6、UserDTO

@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class UserDTO implements Serializable {/*** 用户名*/private String username;/*** 密码*/private String password;}

二、创建过滤器

2.1、MyFilter

/*** @Author : 一叶浮萍归大海* @Date: 2023/11/4 20:37* @Description:*/
@Slf4j
@Component
@WebFilter(urlPatterns = "/*", filterName = "channelFilter")
public class MyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {log.info("============= MyFilter init =============");}/***      普通的参数可以通过request.getParameterMap中获取,而Controller层被@RequestBody修饰的参数需要从request的InputStream中获取,* 但是由于InputStream只能读取一次,如果过滤器读取了参数,那么后面的拦截器和Controller层就读取不到参数了,所以这类参数需要单独获取,可以把* request封装一下,copy一份request,一个用于在拦截器(过滤器)中读取参数,一个放行给Controller使用* * @param request* @param response* @param chain* @throws ServletException* @throws IOException*/@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {ServletRequest requestWrapper = null;String param = "";if (request instanceof HttpServletRequest) {HttpServletRequest httpServletRequest = (HttpServletRequest) request;String method = httpServletRequest.getMethod().toUpperCase();String type = httpServletRequest.getContentType();if (WebRequestConstant.METHOD_TYPE_POST.equals(method) && WebRequestConstant.CONTENT_TYPE_APPLICATION_JSON.equalsIgnoreCase(type)) {try {requestWrapper = new MyHttpServletRequestWrapper((HttpServletRequest) request);} catch (Exception e) {throw new RuntimeException(e);}}}if (requestWrapper == null) {Map<String, String[]> originRequestMap = request.getParameterMap();Map<String, String> requestMap = new HashMap<String, String>(16);for (String key : originRequestMap.keySet()) {String[] values = originRequestMap.get(key);requestMap.put(key, values[0]);}param = JSON.toJSONString(requestMap);} else {param = ((MyHttpServletRequestWrapper) requestWrapper).getBody();}log.info("过滤器param:{}", param);//放行if (requestWrapper == null) {chain.doFilter(request, response);} else {chain.doFilter(requestWrapper, response);}}@Overridepublic void destroy() {log.info("============= MyFilter destroy =============");}}

三、拦截器

3.1、创建拦截器

/*** @Author : 一叶浮萍归大海* @Date: 2023/11/4 18:29* @Description: 自定义的登录拦截器*/
@Slf4j
@Component
public class MyLoginHandlerInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse response, Object handler) throws Exception {log.info("============= MyLoginHandlerInterceptor preHandle =============");try {String requestUrl = httpServletRequest.getRequestURI();ServletRequest requestWrapper = null;String param = "";String method = httpServletRequest.getMethod().toUpperCase();String type = httpServletRequest.getContentType();if (WebRequestConstant.METHOD_TYPE_POST.equals(method) && WebRequestConstant.CONTENT_TYPE_APPLICATION_JSON.equalsIgnoreCase(type)) {requestWrapper = new MyHttpServletRequestWrapper(httpServletRequest);}if (requestWrapper == null) {Map<String, String[]> originRequestMap = httpServletRequest.getParameterMap();Map<String, String> requestMap = new HashMap<String, String>(16);for (String key : originRequestMap.keySet()) {String[] values = originRequestMap.get(key);requestMap.put(key, values[0]);}param = JSON.toJSONString(requestMap);} else {param = ((MyHttpServletRequestWrapper) requestWrapper).getBody();}log.info("拦截器param:{}", param);} catch (Exception e) {e.printStackTrace();}return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {log.info("============= MyLoginHandlerInterceptor postHandle =============");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {log.info("============= MyLoginHandlerInterceptor afterCompletion =============");}
}

3.2、注册拦截器

/*** @Author : 一叶浮萍归大海* @Date: 2023/11/4 18:37* @Description:*/
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {/*** 引入自定义的拦截器对象*/@Resourceprivate MyLoginHandlerInterceptor loginHandlerInterceptor;/*** 注册拦截器* @param registry*      addPathPatterns("/**"):拦截所有*      excludePathPatterns("/business/*"):放行以/business打头的请求*/@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginHandlerInterceptor).addPathPatterns("/**").excludePathPatterns("/business/*").order(1);// registry.addInterceptor(loginHandlerInterceptor).addPathPatterns("/**");}
}

四、使用拦截器(案例)

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

4.1.1、LoginController#login()

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

4.1.2、测试

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

4.2.1、LoginController#login2()

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

4.2.2、测试#form-data

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

4.3、获取Controller层字符串参数

4.3.1、LoginController#login3()

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

4.3.2、测试

五、参考

https://blog.csdn.net/w_t_y_y/article/details/103407841https://blog.csdn.net/weixin_45100881/article/details/128660421

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

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

相关文章

分享一下怎么做小程序营销活动

小程序营销活动已经成为现代营销的必备利器&#xff0c;它能够帮助企业提高品牌知名度、促进产品销售&#xff0c;以及加强与用户的互动。然而&#xff0c;要想成功地策划和执行一个小程序营销活动&#xff0c;需要精心设计和全面规划。本文将为您介绍小程序营销活动的策划和执…

OpenSign 开源 PDF 电子签名解决方案

OpenSign 是一个开源文档电子签名解决方案&#xff0c;旨在为 DocuSign、PandaDoc、SignNow、Adobe Sign、Smartwaiver、SignRequest、HelloSign 和 Zoho Sign 等商业平台提供安全、可靠且免费的替代方案。 特性&#xff1a; 安全签名&#xff1a;利用最先进的加密算法来确保…

easyHttp -- 轻量级的 HTTP 客户端工具包

easyHttp gitte地址:easy-http 介绍 easyHttp 是一个轻量级的 HTTP 客户端工具包&#xff0c;专为 Java 设计&#xff0c;使得基本的 HTTP 请求变得异常简单。该库主要针对常见的 HTTP 请求提供了简洁的 API&#xff0c;使得开发者无需面对复杂的设置。当前版本已支持基本的请…

私有化部署大模型:5个.Net开源项目

从零构建.Net前后端分离项目 今天一起盘点下&#xff0c;10月份推荐的5个.Net开源项目&#xff08;点击标题查看详情&#xff09;。 1、BootstrapBlazor企业级组件库&#xff1a;前端开发的革新之路 BootstrapBlazor是一个用于构建现代Web应用程序的开源框架&#xff0c;它基…

Jmeter分布式压测 —— 易踩坑点

1、压测机 无论是从成本角度还是维护的难易方面&#xff0c;压测机的数量&#xff0c;适量就好。举个例子&#xff0c;8C16G的一台服务器&#xff0c;部署Jmeter后&#xff0c;根据我个人的测试比对数据&#xff0c;配置≤1500个线程数&#xff0c;最好。太多了性能损耗较大&a…

QT实现的一个MVP设计模式demo

最近做qt 项目,发现网上基于MVP设计模式的QT例程很少&#xff0c;这里写一个demo示例可作为参考&#xff1a; 一、简要概述 MVP是由MVC发展而来&#xff0c;总体目的与作用相同。都是为了软件构架有层次之分&#xff0c;使得核心逻辑、界面控制、数据这三者分层清晰明了。减少…

RabbitMQ 死信队列

在MQ中&#xff0c;当消息成为死信&#xff08;Dead message&#xff09;后&#xff0c;消息中间件可以将其从当前队列发送到另一个队列中&#xff0c;这个队列就是死信队列。而在RabbitMQ中&#xff0c;由于有交换机的概念&#xff0c;实际是将死信发送给了死信交换机&#xf…

要在CentOS中安装Docker

Docker部署 在CentOS中安装Docker要在CentOS中安装Docker&#xff0c;请按照以下步骤进行操作&#xff1a;启动和校验常用命令查看容器启动容器 配置镜像加速 在CentOS中安装Docker 要在CentOS中安装Docker&#xff0c;请按照以下步骤进行操作&#xff1a; 首先&#xff0c;确…

apache-maven-3.6.3 安装配置教程

链接&#xff1a;https://pan.baidu.com/s/1RkMXipnvac9EKcZyUStfGQ?pwdl32m 提取码&#xff1a;l32m 1. 将 maven 压缩包解压至指定文件夹 2. 配置环境变量 &#xff08;1&#xff09;打开此电脑-> 鼠标右键选择属性->点击高级系统设置 &#xff08;2&#xff09;点…

软件测试简历这样写,一周能约七个面试

简历到底有多重要&#xff1f; 俗话说&#xff1a;“简历就是你能否进入一家公司的敲门砖”。面试官只有看到一份有质量的简历才会给你一个面试的机会。 很多人都会有这样的问题&#xff0c;为什么我投了那么多简历&#xff0c;都没有接到面试通知&#xff1f;也没有HR和我电…

“菊风Juphoon”邀您莅临11月22-24日CNF南京应急展消防展 | 展位号:115-1

公司简介 菊风依托互联网和电信网音视频融合技术积累&#xff0c;提供智能化的音视频统一通信产品及服务。面向应急管理、消防救援、智慧城市等多个领域&#xff0c;菊风推出适用于全网通的统一通信一体机、统一通信平台。 此外&#xff0c;菊风还提供视频能力平台&#xff0…

JavaScript设计模式之责任链模式

适用场景&#xff1a;一个完整的流程&#xff0c;中间分成多个环节&#xff0c;各个环节之间存在一定的顺序关系&#xff0c;同时中间的环节的个数不一定&#xff0c;可能添加环节&#xff0c;也可能减少环节&#xff0c;只要保证顺序关系就可以。 如下图&#xff1a; ES5写法…

Qt QTableView排序

1.简介 在开发过程中&#xff0c;我们需要通过点击表头来对QTableView或QTreeView等一系列高级视图进行排序操作&#xff0c;以下是进行排序的步骤。 步骤&#xff1a; 首先创建了一个QStandardItemModel对象或者继承QAbstractTableModel类作为数据模型&#xff0c;并设置了…

如何实现Word文档中的书签双向定位

工作中&#xff0c;经常需要拟定合同&#xff0c;一般都有固定的模板&#xff0c;在特定的位置填写内容。通过zOffice编辑合同文件时&#xff0c;可以在模板需要填写的位置预设书签&#xff0c;配合zOffice SDK使用&#xff0c;利用zOffice书签双向定位的特性&#xff0c;更方便…

4.求1000以内的所有完数

#include<stdio.h> // 完数&#xff1a;一个数的所有的真因子 (即除了自身以外的约数)的和&#xff0c;恰好等于它自身 // 1 不是完数 // 4的因子&#xff1a;1 2 4 除了本身 4 不等于 1&#xff0b;2 所以4不是完数void fun(void){int sum,i,j;for(i2;i<1000;i)…

C语言--结构体(内容超级详细)

一.前言 通过数据类型来定义一个一个的变量,当需要很多相同类型的变量时有数组。基本数据类型在使用时 很方便,但是利用它们来描述现实世界就显得捉襟见肘。例如需要保存一个班学生的信息”姓名,年龄,分 数”,按照前面的学习需要单独定义三个数组,一个保存姓名,一个保存年龄,一…

如何使新手小白编码能力暴涨之Devchat-AI

在这个快速发展的时代&#xff0c;开发者的任务越来越繁重&#xff0c;要求他们快速、高效地完成开发任务。然而&#xff0c;传统的开发方式已经无法满足这个需求。在这种情况下&#xff0c;Devchat的出现给开发者带来了新的帮助。Devchat是一个研发效能分析平台&#xff0c;它…

Java8强大的新特性 —— “Stream API”

一、什么是Stream API&#xff1f; Java Stream API是Java 8中引入的一个重要功能&#xff0c;它允许开发者以声明性方式处理数据集合&#xff0c;使代码更加简洁、可读性更好&#xff0c;同时还提供了并行操作的能力&#xff0c;从而能够更有效地利用多核处理器。 Stream AP…

【达梦数据库】学习笔记

【达梦数据库】学习笔记 【一】如何使用idea连接达梦数据库【二】idea项目导入本地的达梦数据库驱动jar包 【一】如何使用idea连接达梦数据库 &#xff08;1&#xff09;打开idea&#xff0c;点击右上角的数据库 &#xff08;2&#xff09;把达梦数据库的jar包配置一下 找到…

Centos7部署Python3环境

一、安装Python3 ###查看是否安装Python3 Centos 7 默认安装了python 2.7.5. 因为一些命令要用它比如yum 它使用的是python2.7.5 使用 python -V 命令查看一下是否安装Python 然后使用命令 which python 查看一下Python可执行文件的位置 Python指向的是Python2.7 安装依赖 y…