当前位置: 首页 > news >正文

通过HandlerMethodArgumentResolver实现统一添加接口入参参数

背景:项目中有些接口的入参需要用户id信息,最简单的做法在每个Controller方法调用的时候获取登录信息然后给入参设置用户id,但是这样就会有很多重复性的工作。另一个可行的也更好的方案可以使用HandlerMethodArgumentResolver来实现。

部分示例代码如下:

1、需要用户id的入参基类
@Data
@ToString
public class WarehouseBaseReq implements Serializable {private String userId;
}
2、新增自定义的解析器处理接口入参设置用户id
@Slf4j
@Component
public class LycMethodArgumentResolver implements HandlerMethodArgumentResolver, InitializingBean {@Autowiredprivate RequestMappingHandlerAdapter adapter;private HandlerMethodArgumentResolver delegate;@Overridepublic void afterPropertiesSet() throws Exception {List<HandlerMethodArgumentResolver> argumentResolvers = adapter.getArgumentResolvers();List<HandlerMethodArgumentResolver> resolverList = new ArrayList<>(argumentResolvers);// 用自定义的resolver代理decorateResolvers(resolverList);adapter.setArgumentResolvers(resolverList);}@Overridepublic boolean supportsParameter(MethodParameter methodParameter) {return delegate.supportsParameter(methodParameter);}@Overridepublic Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {Object obj = delegate.resolveArgument(methodParameter,mavContainer,webRequest,binderFactory);// 判断只有当入参是指定类型才设置if (obj instanceof WarehouseBaseReq) {WarehouseBaseReq requestObj = (WarehouseBaseReq)obj;// 从ThreadLocal中获取登录用户信息UserDto userDto = UserThreadLocal.getUser();if (null != userDto) {// 给接口入参设置用户idrequestObj.setUserId(userDto.getId());}}return obj;}private void decorateResolvers(List<HandlerMethodArgumentResolver> resolverList){for (int i=0; i<resolverList.size();i++){HandlerMethodArgumentResolver resolver = resolverList.get(i);if (resolver instanceof RequestResponseBodyMethodProcessor){this.delegate = resolver;resolverList.set(i,this);break;}}}
}
3、模拟查询仓库的入参
@Data
@ToString(callSuper = true)
public class WarehouseDto extends WarehouseBaseReq {private Long warehouseId;private String warehouseName;private String warehouseCode;
}
4、模拟查询仓库的controller方法
@RestController
@RequestMapping("/web/warehouse")
public class WarehouseController {@Autowiredprivate WarehouseBizService warehouseBizService;@RequestMapping("/testById")public BizRsp<WarehouseDto> testQueryById(@RequestBody WarehouseDto warehouseDto) {log.info("testQueryById方法执行,warehouseDto:{}",warehouseDto);LearingAssert.notNull(warehouseDto.getUserId(),"用户id不能为空");return BizRspUtil.success(warehouseBizService.queryById(warehouseDto));}
}
5、postman中模拟调用接口,入参只需要传递其他参数,结构如下:

{
“warehouseId”:1
}

自此调用方无需传递用户id,controller的方法也无需写重复代码设置用户id即可实现统一添加接口入参参数的效果。
在spring中还有其他一些处理器,可在一些场景下帮助我们更好的实现一些功能。

参考博客:
[1] spring中的各种处理器
[2]方法参数解析器

http://www.lryc.cn/news/110233.html

相关文章:

  • JAVA-spring boot 2.4.X报错Unable to find GatewayFilterFactory with name Hystrix
  • 运输层---UDP协议
  • 【LeetCode】剑指 Offer Ⅱ 第3章:字符串(7道题) -- Java Version
  • 【python】绘图代码模板
  • RTT学习笔记12-KConfig 语法学习
  • 基于Mediapipe的姿势识别并同步到Unity人体模型中
  • Linux下进程的特点与环境变量
  • 以Llama-2为例,在生成模型中使用自定义LogitsProcessor
  • python 计算图片hash 缓存图片为key
  • 制造型企业如何实现车间设备生产数据的实时采集?需要5G网络吗?
  • 第2章 HTML中的JavaScript
  • 景联文科技高质量成品数据集上新啦!
  • flask------请求拓展
  • 大数据-玩转数据-FLINK-从kafka消费数据
  • 介绍Sping Boot的5个扩展点
  • Linux2.6内核配置说明
  • Pytest简介及jenkins集成
  • 【LeetCode】105. 从前序与中序遍历序列构造二叉树 106. 从中序与后序遍历序列构造二叉树
  • 堆内存和一些检测工具
  • 【JavaScript】元素获取指南
  • uniapp 返回上一页并刷新
  • Java阶段五Day21
  • 2023,谁在引领实时互动进入高清时代?
  • STM32(HAL)串口中断接收
  • word转pdf怎么转?几种常用方法分享
  • 自学(黑客)技术,入门到入狱!
  • js 函数、闭包及函数对象
  • SSM(Vue3+ElementPlus+Axios+SSM前后端分离)--搭建Vue 前端工程[二]
  • Android 之 AudioManager ( 音频管理器 )
  • 2023爱分析·超自动化厂商全景报告|爱分析报告