Spring MVC通过拦截器记录请求处理日志

方案:
.接口列表保存在数据库表中, 指定是否记录日志以及日志模板.默认提取body,path variables,query properties的值(去除敏感属性)
.通过拦截器在请求处理后记录请求处理日志(HandlerInterceptor#postHandle)


。接口列表保存在sys_func表中:
示例记录:

insert into sys_func(id,name,method,path,grant_flag,log_flag) values(1,'测试-1',1,'/trade/order/test/{name}',1,1);

method: HTTP方法编码. 1-POST
path: 接口path
log_flag:是否记录日志.
sys_func表的log_template定义输出日志的模板.


。如何确认HttpServletRequest对应的sys_func记录呢?

方法1:
    逻辑:HttpServletRequest执行的是什么方法,在RequestMappingHandlerMapping查找该方法对应的@RequestMapping信息。确定method,path。

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView modelAndView) throws Exception {
        /// 获取RequestMapping与handler映射
        RequestMappingHandlerMapping mapping = ApplicationContextUtil.getBean(RequestMappingHandlerMapping.class);
        /// 当前请求的HandlerExecutionChain
        HandlerExecutionChain handlerExecutionChain = mapping.getHandler(request);
        HandlerMethod handlerMethod = (HandlerMethod) handlerExecutionChain.getHandler();
        ///< 从request获取到了执行的方法
        Method method = handlerMethod.getMethod();
        /// 找到方法对应的map设置信息: 得到原始的method,path信息
        Map<RequestMappingInfo, HandlerMethod> handlerMethodMapping = mapping.getHandlerMethods();
        RequestMappingInfo requestMappingInfo = handlerMethodMapping.entrySet().stream().filter(e->
            e.getValue().getMethod().equals(method)
        ).map(Map.Entry::getKey).findFirst().orElse(null);
        if (requestMappingInfo==null)
            return;
        /// 确定method,path
        Set<RequestMethod>  methods = requestMappingInfo.getMethodsCondition().getMethods();
        if (methods.isEmpty())
            return;
        String methodName = ((RequestMethod)methods.toArray()[0]).name();
        Set<String> patterns =  requestMappingInfo.getPatternsCondition().getPatterns();
        if (patterns.isEmpty())
            return;
        String path = (String) patterns.toArray()[0];


        /// 跟数据库信息比较,确定sys_func记录.
        FuncDto func = ParameterExtractor.findFunc(methodName,path);
        if (func==null)
            return;
        
        ///写日志
    }


方法2:
    为sys_func的每个接口记录,创建MvcRequestMatcher,建立映射。
    拦截时查找匹配HttpServletRequest的MvcRequestMatcher,确定sys_func记录。

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView modelAndView) throws Exception {
        FuncDto func = matchers.entrySet().stream().filter(e->e.getKey().matches(request)).map(Map.Entry::getValue).findFirst().orElse(null);
        if (func==null)
            return;

        ///写日志
    }


    /// 支持代码
 

   private Map<MvcRequestMatcher,FuncDto> matchers = new HashMap<>();

    @PostConstruct
    private void init() {
        boolean isServlet30 = ClassUtils.isPresent("javax.servlet.ServletRegistration", getClass().getClassLoader());
        ObjectPostProcessor<Object> opp = ApplicationContextUtil.getBean(ObjectPostProcessor.class);
        HandlerMappingIntrospector introspector = new HandlerMappingIntrospector();
        ParameterExtractor.funcs.forEach(e->{
            MvcRequestMatcher matcher = new MvcRequestMatcher(introspector, e.getPath());
            if (isServlet30) {
                opp.postProcess(matcher);
            }

            HttpMethod httpMethod;
            switch(e.getMethod()) {
                case POST :httpMethod = HttpMethod.POST; break;
                case GET: httpMethod = HttpMethod.GET; break;
                case PATCH: httpMethod = HttpMethod.PATCH; break;
                case DELETE: httpMethod = HttpMethod.DELETE; break;
                default:
                    return;
            }
            matcher.setMethod(httpMethod);
            matchers.put(matcher,e);
        });
    }


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值