需求场景
request请求的参数有大概 3种,怎样一次性 都获取出来呢 ?
-
get 请求
?param1=hello¶m2=world,直接用request.getParameter()获取单个参数,或者
request.getParameterMap()获取 多个参数为map格式 -
restful 请求 ,借助 spring实现
(Map)request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE) -
post 请求的参数,读取 stream 流 ,
request.getInputStream()获取 。 该方法只允许调用1次,因为 stream的流指针没有复位,导致后续执行会报错。因此,我们需要 提前 封装一下它的内容 到 buffer 中,曲线救国实现 多次读取 。
为什么不用aop?
- 原理:
- 拦截器的实现原理是 HandlerMapping 根据request的url和注解信息等,找到拦截器调用链中的每个Interceptor,然后传递 request 进去依次执行。不涉及 动态代理
- 对比而言,aop是动态代理,每次都需要生成1个实现类,就问 cpu和内存 累不累,code monkey 累不累
- 代码太啰嗦,用的人太多 烂大街了。
- 大量重复的代码,一点也不高雅。
- 需要换个口味,回归自然,回归简单,如 诺基亚C20L plus 一般。
实现方案 : filter + interceptor + request 参数,最干净的原始编程
- filter 封装request对象,使其 内部的 stream 流可以 多次 读
- interceptor 拦截每次 指定的 请求, 获取 request 对象中的 所有parameters ,并且最终 放入 1 个map 中 返回
废话少说,搞起:
-
WrapRequestFilter过滤器,封装request 对象,替换 原有的request,支持 多次 执行request.getInputStream()/** * enable the ability to read request-params multiple times * by copying the request stream into a byte[] buffer. * getInputStream() & getReader() are both override to read this buffer * * @author stormfeng * @date 2021-08-12 10:30 * <p> * reference :https://blog.youkuaiyun.com/dark_horse_lk/article/details/82344692 */ @WebFilter(urlPatterns = "/api/*") @Order(2) public class WrapRequestFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { ServletRequest requestWrapper = new BufferedServletRequestWrapper(request); chain.doFilter(requestWrapper, response); } private static class BufferedServletRequestWrapper extends HttpServletRequestWrapper { private byte[] buffer; public BufferedServletRequestWrapper(HttpServletRequest request) throws IOException { super(request); InputStream is = request.getInputStream(); this.buffer = StreamUtils.copyToByteArray(is); } // 外部 读取字节流 的方法 @Override public ServletInputStream

本文介绍了如何在Spring Boot应用中,不使用AOP而是通过Filter和Interceptor来优雅地获取所有请求参数。作者指出AOP的动态代理机制在效率上存在不足,并给出了一种原始编程的解决方案。通过创建一个`WrapRequestFilter`来封装request对象,使其支持多次读取输入流,然后使用Interceptor工具类`InterceptorUtils`来整合GET、RESTful和POST请求的参数。文章还提供了一个获取特定参数的方法,并在最后总结了这种方法在权限控制和缓存等方面的优点。
最低0.47元/天 解锁文章
353

被折叠的 条评论
为什么被折叠?



