阿昌教你自定义拦截器&自定义参数解析器&自定义包装HttpServletRequest

最后

分享一些资料给大家,我觉得这些都是很有用的东西,大家也可以跟着来学习,查漏补缺。

《Java高级面试》

《Java高级架构知识》

《算法知识》

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

那这里有一个问题,HandlerMethod是什么东西?他为什么会能有getMethodAnnotation()方法去拿到给他传入的.class的注解呢?

那这里就要引出SpringMVC了,如果你学了它,你就会知道HandlerMethod,其实就对应Handler,也就是我们写的那些Controller

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-evJ0gltZ-1636094064359)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211105130036365.png)]

那知道了这个之后,根据上面的handler instanceof HandlerMethod来判断他是不是controller,如果是,那就可以拿到controller上面所标记的注解,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dx4FoD8I-1636094064360)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211105133517499.png)]

以上就可以看到了@Login所进行的流程,最后写了以上的还是不行的,我们需要将这个拦截器加入到spring的拦截器链表中也就是上面的图,让他起作用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I4P9RDrY-1636094064362)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211105130758648.png)]

查找了下代码,他在com.tduck.cloud.api.config.WebMvcConfig中实现了WebMvcConfigurer

重写了addInterceptors(InterceptorRegistry registry)方法,把上面写的登录校验加入拦截器链中,并指定拦截所有请求!

在这里插入图片描述

这里的最后,查看他随便使用到@Login注解的地方,所以标注了它后会在拦截器中进行对token的校验,来判断用户是否登录

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aVaLP7BX-1636094064363)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211105131304240.png)]


@LoginUser


com.tduck.cloud.api.annotation.LoginUser

通过这个注解去控制这个某个参数封装用户信息

给他定义的是:描述参数/运行时生效

/**

  • 登录用户信息

*/

@Target(ElementType.PARAMETER)

@Retention(RetentionPolicy.RUNTIME)

public @interface LoginUser {}

在项目中查找@LoginUser注解,发现在com.tduck.cloud.api.web.resolver.LoginUserHandlerMethodArgumentResolver中,他实现了HandlerMethodArgumentResolver参数解析器,他就是解析请求发来的参数并解析成对应我们controller中对应方法参数,比如@RequestBody、@RequestParam等

HandlerMethodArgumentResolver的小文章 •‾̑⌣‾̑•) 】

在这里插入图片描述

需要获取到请求来的参数,并封装。

但是这里需要自定义,因为SpringMVC只封装对应的请求体,这里就直接自定义写了一个封装器

@Component

public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

private final UserService userService;

//通过构造依赖,需要的userService

public LoginUserHandlerMethodArgumentResolver(UserService userService) {

this.userService = userService;

}

//这个方法返回的T/F,会直接决定下面的resolveArgument()方法是否能够被执行

@Override

public boolean supportsParameter(MethodParameter parameter) {

//拿到这个请求参数的类型

//判断他是不是UserEntity类,并判断他是不是有被注解@LoginUser标注

return parameter.getParameterType().isAssignableFrom(UserEntity.class) && parameter.hasParameterAnnotation(LoginUser.class);

}

@Override

public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container,

NativeWebRequest request, WebDataBinderFactory factory) throws Exception {

//从请求域中拿到用户的id

//这个用户的id是在 【@Login的拦截器里面最后放入到请求域中的】

Object object = request.getAttribute(AuthorizationInterceptor.USER_KEY, RequestAttributes.SCOPE_REQUEST);

if (object == null) {

return null;

}

//获取用户信息,并返回,返回后spring会自动给UserEntity类封装上查询到的信息

UserEntity user = userService.getById((Long) object);

return user;

}

}

最后写完了肯定要加入到MVCArgumentResolvers参数解析器s中,

com.tduck.cloud.api.config.WebMvcConfig

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EWdIGEV5-1636094064365)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211105132858992.png)]

这样子,主要标注了@LoginUser的注解就会被这个参数解析器解析,并自动去查询获取封装对应的用户数据

同样这里的最后,也查看羡慕使用到@LoginUser注解的地方,发现他使用的方式跟我们常用的各种封装数据类型的注解一模一样

com.tduck.cloud.api.web.controller.UserController

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8LhOmklW-1636094064366)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211105133818884.png)]


@NoRepeatSubmit


com.tduck.cloud.api.annotation.NoRepeatSubmit

最后一个注解,通过它来控制不允许重复提交

给他定义的是:描述方法、描述类&接口/运行时生效

/**

  • 不允许重复提交注解

*/

@Target({ElementType.METHOD, ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

public @interface NoRepeatSubmit {}

如果你观察仔细,你在上面就会已经发现了这个注解的拦截器跟@Login的拦截器在同一个包下

com.tduck.cloud.api.web.interceptor.NoRepeatSubmitInterceptor

不同的是,他是直接实现的HandlerInterceptor,而@Login的拦截器是继承HandlerInterceptor的一个实现类HandlerInterceptorAdapter

HandlerInterceptor&HandlerInterceptorAdapter区别 】 ´•.̫ • `


它先判断是否是HandlerMethod,就是判断是不是Handler处理器,如果不是,就直接结束返回true;

强转,并再判断他是否又被@NoRepeatSubmit标注,如果有就继续,不然就直接结束返回true;

在这里看到,他通过自定义的方式跟@Login是一样的 (ฅ´ω`ฅ)!!!

在这里插入图片描述

然后判断是否是BodyReaderHttpServletRequestWrapper

在这里插入图片描述

BodyReaderHttpServletRequestWrapper是什么东西???

关联打开后发现代码很多!!! 且发现他继承了HttpServletRequestWrapper

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uQPn1r2C-1636094064368)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211105135348168.png)]

那问题就转移了,就是HttpServletRequestWrapper是什么??? 【 HttpServletRequestWrapper类的作用

这里简单的概括就是因为我们很多时候都要改变HttpServletRequest,但是由于java.util.Map包装的HttpServletRequest对象的参数是不可改变,所以通过 【装饰者设计模式 】包装来改变其状态,这样子只需要在装饰类HttpServletRequestWrapper中,按照需要重写其对应的方法即可

com.tduck.cloud.api.web.wrapper.BodyReaderHttpServletRequestWrapper

进行了对原HttpServletRequest包装装饰,给每一个参数内容都加上了XSS过滤

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zR1fZARr-1636094064369)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211105135533641.png)]

最后

分布式技术专题+面试解析+相关的手写和学习的笔记pdf

还有更多Java笔记分享如下:

image

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

color_FFFFFF,t_70,g_se,x_16)

最后

分布式技术专题+面试解析+相关的手写和学习的笔记pdf

还有更多Java笔记分享如下:

[外链图片转存中…(img-hgAvsUAy-1715712059148)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 12
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
通过docker搭建Redis集群的步骤如下: 1. 创建容:使用docker命令创建多个Redis容,每个容代表一个节点。例如,可以使用以下命令创建一个名为redis-node-1的节点容: ``` docker run --name redis-node-1 -p 6381:6379 -d redis ``` 2. 进入容:使用docker exec命令进入容内部,例如,可以使用以下命令进入redis-node-1容: ``` docker exec -it redis-node-1 /bin/bash ``` 3. 构建集群关系:在容内部,使用Redis命令行工具,将新增的节点作为master节点加入原集群。例如,可以使用以下命令将节点redis-node-7加入集群: ``` redis-cli -p 6381 cluster add-node <new_node_ip:port> <existing_node_ip:port> ``` 4. 查看集群状态:使用Redis命令行工具查看集群的状态。例如,可以使用以下命令在节点redis-node-1上查看集群信息: ``` redis-cli -p 6381 cluster info ``` 通过以上步骤,你可以使用docker搭建Redis集群,并查看集群的状态。请根据实际情况进行操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [阿昌你通过docker搭建Redis集群](https://blog.csdn.net/qq_43284469/article/details/122458602)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值