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;
        }
  • 相关阅读:
    Java 蓝桥杯 算法训练 貌似化学
    Java 蓝桥杯 算法训练 貌似化学
    Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
    Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
    Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
    Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
    Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
    JAVA-蓝桥杯-算法训练-字符串变换
    Ceph:一个开源的 Linux PB 级分布式文件系统
    shell 脚本监控程序是否正在执行, 如果没有执行, 则自动启动该进程
  • 原文地址:https://www.cnblogs.com/nxzblogs/p/10787513.html
Copyright © 2011-2022 走看看