• Springboot关于在拦截器中打印相关日志和鉴权的若干点


    需求:在filter中进行请求日志的打印(有时候是因为数据的序列化出错),做简单鉴权

    java中springboot,request body InputStream流的读取只能读取一次,读完就没,如果在filter中直接读取了,到controller中数据就拿不到了。所以springboot提供了 ContentCachingRequestWrapper 这个类来进行包裹。

    先看这个类的名称可以踩个大概就是做request的缓存用的。

    // 代码如下,基本原理是将原始的request初始化wrappedRequest,然后用这个变量贯穿整个请求过程,
    // 值得注意的是wrappedRequest这个工作原理是read()函数被调用的过程中缓存,也就是说这个原理是springboot/mvc在controller进行body数据读取的时候,读出来了再把数据copy一份到cache中,所以wrappedRequest就能反复读取数据。
    // 在下列代码中 执行的顺序 是 doFilter() 调用 read()函数,wrappedRequest中的数据就被copy完毕,所以recordReq() 和 recordResp() 函数参数就能访问到请求数据,如果不使用wrappedRequest,那么数据读取完后request中数据就空了。
    // 这边值得注意的是在权限验证失败时候手动调用了wrappedRequest.getReader().read(),意在将数据刷到wrappedRequest中。
    @Component
    @WebFilter(filterName = "authenticationFilter", urlPatterns = "/*")
    @Order(-9999)
    @Slf4j
    public class AuthenticationFilter extends GenericFilterBean {
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
                throws IOException, ServletException {
            ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper((HttpServletRequest) servletRequest);
            ContentCachingResponseWrapper wrappedResponse = new ContentCachingResponseWrapper((HttpServletResponse) servletResponse);
            // 授权认证
            Optional<String> origin = authentication(wrappedRequest);
            long start = TimeUtils.getLongTimeMillis();
            if (origin.isEmpty()) {
                // 手动读取,将结果刷新到wrappedRequest中
                wrappedRequest.getReader().read();
                // 为携带Token
                wrappedResponse.setStatus(HttpServletResponse.SC_OK);
                String str = GsonUtils.toJson(BaseResponse.fail(ResultCode.AUTHORIZE_FAILED));
                //设置 HttpServletResponse使用utf-8编码
                wrappedResponse.setCharacterEncoding("utf-8");
                //设置响应头的编码
                wrappedResponse.setHeader("Content-Type", "application/json;charset=utf-8");
                wrappedResponse.getWriter().write(str);
            } else {
                chain.doFilter(wrappedRequest, wrappedResponse);
            }
            long end = TimeUtils.getLongTimeMillis();
            // 记录请求信息
            recordReq(wrappedRequest, origin);
            // 记录response信息
            recordResp(wrappedRequest, wrappedResponse, end - start);
            // 这一步很重要,把缓存的响应内容,输出到客户端
            wrappedResponse.copyBodyToResponse();
        }
    }
    
  • 相关阅读:
    GridView编辑删除取消完整代码
    添加删除组件里没有IIS
    关于网站开发中存在的问题
    网络公司网站源码介绍Version1.0
    IIS 状态代码
    收藏常用的快捷方式
    连接池已经满的解决方案
    Do you choose a experienced employee with highsalary or a inexperienced employee with lowsalary?
    Registered Permanent residence/attitude for sports
    数据缓存依赖
  • 原文地址:https://www.cnblogs.com/monster5475/p/16285790.html
Copyright © 2020-2023  润新知