zoukankan      html  css  js  c++  java
  • 拦截请求并记录相应信息-springboot

    方式:

    1、FIlter过滤器

    2、interceptor拦截器

    3、Aspect切片

    一、Filter过滤器形式

      只能处理request中的数据  不能确定请求要走的是哪个controller信息

    1、过滤器实现第一种方式

    package com.nxz.filter;
    
    import org.springframework.stereotype.Component;
    
    import javax.servlet.*;
    import java.io.IOException;
    import java.util.Date;
    
    // Filter 是javax.servlet下的
    @Component //让自定义filter起作用,只需要让springcontext管理起来即可
    public class TimeFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("time filter init");
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("time filter start");
            long time = new Date().getTime();
            filterChain.doFilter(servletRequest, servletResponse);
            System.out.println("消耗时间:" + (new Date().getTime() - time));
            System.out.println("time filter start");
        }
    
        @Override
        public void destroy() {
            System.out.println("time filter destroy");
        }
    }

    当项目启动的时候会在控制台输出:time filter init

    当访问localhost:8080/user/1时:进入拦截器

    结束结束后:

    time filter start
    进入getinfo服务
    消耗时间:367
    time filter end

    2、filter过滤器第二种方式

    package com.nxz.filter;
    
    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class WebConfig {
    
        @Bean
        public FilterRegistrationBean timeFilter(){
    
            FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
    
            TimeFilter timeFilter = new TimeFilter();
            filterRegistrationBean.setFilter(timeFilter);
    
            //指定什么样的请求回走timefilter过滤器
            filterRegistrationBean.addUrlPatterns("/*");
            return filterRegistrationBean;
        }
    }

    二、inteceptor拦截器

      只能处理到类中的方法,但是不能记录方法的参数是什么

    package com.nxz.inteceptor;
    
    import org.springframework.stereotype.Component;
    import org.springframework.web.method.HandlerMethod;
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.util.Date;
    
    @Component
    public class TimeInteceptor implements HandlerInterceptor {
    
        //在controller调用之前调用
        @Override
        public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
            System.out.println("preHandler");
    
            System.out.println(((HandlerMethod) o).getBean().getClass().getName());//输出类名
            System.out.println(((HandlerMethod) o).getMethod().getName());//输出方法名
    
            //为了在prehandler方法和posthandler方法之间传递信息,可以将数据放到request中
            httpServletRequest.setAttribute("startTime", new Date().getTime());
            return false;
        }
    
        //在controller调用之后调用,如果controller中抛出异常,这个方法不会调用
        @Override
        public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
            System.out.println("postHandle");
            Long start = (Long) httpServletRequest.getAttribute("startTime");
            System.out.println("time interceptor 耗时:" + (new Date().getTime() - start));
        }
    
        //无论controller是否抛出异常,都会调用
        @Override
        public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
            System.out.println("afterCompletion");
            Long start = (Long) httpServletRequest.getAttribute("startTime");
            System.out.println("time interceptor 耗时:" + (new Date().getTime() - start));
            System.out.println("ex is :" + e);
        }
    }

    interceptor实现拦截功能还需要配置webconfig

    package com.nxz.config;
    
    import com.nxz.filter.TimeFilter;
    import com.nxz.inteceptor.TimeInteceptor;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    
    @Configuration
    public class WebConfig extends WebMvcConfigurerAdapter {
    
        @Autowired
        private TimeInteceptor timeInteceptor;
        //自定义的interceptor 要起作用的话 需要继承webmvcConfigurerAdater ,重写addInterceptors
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(timeInteceptor);
        }
    }

    访问localhost:8080/user/1后,输入日志:

    preHandler
    com.nxz.controller.UserController 
    getInfo
    进入getinfo服务
    postHandle
    time interceptor 耗时:48
    afterCompletion
    time interceptor 耗时:48
    ex is :null

     三、切片Aspect(AOP)  -- 切入点(注解)、增强(方法)

      需要导入aop依赖

    package com.nxz.aspect;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.stereotype.Component;
    
    import java.util.Date;
    
    @Aspect
    @Component
    public class TimeAspect {
    
        //@Before @After @AfterThrowing @Around 基本的aop注解
    
        @Around("execution(* com.nxz.controller.UserController.*(..))")
        public Object handlerControllerMehtod(ProceedingJoinPoint joinPoint) throws Throwable {
    
            System.out.println("time aspect start");
    
            Object[] args = joinPoint.getArgs();
            for (Object arg : args) {
                System.out.println(arg);
            }
    
            Long time = new Date().getTime();
            Object obj = joinPoint.proceed();
    
            System.out.println("time aspect end,耗时:" + (new Date().getTime() - time));
    
            return obj;
        }
    
    }

    访问地址后:

    time aspect start 
    1   --》请求参数
    进入getinfo服务
    time aspect end,耗时:4

     几种方式起作用的顺序:

    ====

     Usercontroller:

        @GetMapping("/{id:\d+}")
        @JsonView(User.UserDetailView.class)
        public User getInfo(@PathVariable String id) {
            System.out.println("进入getinfo服务");
            User user = new User();
            user.setUsername("tom");
            return user;
        }
  • 相关阅读:
    JQuery中的动画
    javascript之变量、作用域、作用域链
    正确理解javascript的this关键字
    我忽略了的DOCTYPE!
    JQuery中的DOM操作
    发布一款html5移动端scroll框架:xScroll
    在debug时使Flutter中的print打印json数据时更美观易读
    使用ValueListenableBuilder监听TextEditingController
    Flutter使用rxdart和ChangeNotifier实现的倒计时按钮
    Flutter设计一个长按自动步进的按钮
  • 原文地址:https://www.cnblogs.com/nxzblogs/p/10787513.html
Copyright © 2011-2022 走看看