zoukankan      html  css  js  c++  java
  • 008 RestFul API 拦截器

    一:任务

    1.任务

      过滤器Filter

      拦截器Interceptor

      切片Aspect

    二:过滤器

    1.新建包

      

    2.自定义过滤器程序

      加了注解,这个过滤器在springboot中就起作用了

     1 package com.cao.web.filter;
     2 
     3 import java.io.IOException;
     4 import java.util.Date;
     5 
     6 import javax.servlet.Filter;
     7 import javax.servlet.FilterChain;
     8 import javax.servlet.FilterConfig;
     9 import javax.servlet.ServletException;
    10 import javax.servlet.ServletRequest;
    11 import javax.servlet.ServletResponse;
    12 
    13 import org.springframework.stereotype.Component;
    14 
    15 //使得过滤器起作用
    16 @Component
    17 public class TimeFilter implements Filter {
    18 
    19     @Override
    20     public void init(FilterConfig filterConfig) throws ServletException {
    21         System.out.println("time filter init");
    22 
    23     }
    24 
    25     @Override
    26     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    27             throws IOException, ServletException {
    28         System.out.println("time filter start");
    29         //进行下一个调用链
    30         long start=new Date().getTime();
    31         chain.doFilter(request, response);
    32         System.out.println("time filter 耗时: "+(new Date().getTime()-start));
    33         System.out.println("time filter finish");
    34 
    35     }
    36 
    37     @Override
    38     public void destroy() {
    39         System.out.println("time filter destroy");
    40 
    41     }
    42 
    43 }

      将要访问的控制器

     1     @JsonView(User.UserDetailView.class)
     2     @GetMapping(value="/{id:\d+}")
     3     public User getInfo(@PathVariable(value="id") String idid){
     4         /**
     5          *  演示filter调用
     6          */
     7         System.out.println("进入getInfo服务");
     8         
     9         System.out.println("idtt="+idid);
    10         User user=new User();
    11         user.setUsername("tom");
    12         return user;
    13         /**
    14          *  下面的主要是演示Spring booter异常的处理机制,现在先注释掉
    15          */
    16 //        throw new UserNotExistException(idid);
    17         
    18     }

    3.效果

      先启动,这个时候,过滤器一样会被启动

      

      进行访问

      

      效果

      

    4.引用第三方Filter,加到过滤器链上

      在Spring boot上没有web.xml。

      新建一个过滤器,用于表示第三方的过滤器

     1 package com.cao.web.filter;
     2 
     3 import java.io.IOException;
     4 import java.util.Date;
     5 
     6 import javax.servlet.Filter;
     7 import javax.servlet.FilterChain;
     8 import javax.servlet.FilterConfig;
     9 import javax.servlet.ServletException;
    10 import javax.servlet.ServletRequest;
    11 import javax.servlet.ServletResponse;
    12 
    13 import org.springframework.stereotype.Component;
    14 
    15 /**
    16  * 假设这里是一个第三方的Filter,用来演示
    17  * @author dell
    18  *
    19  */
    20 public class TimeFilter2 implements Filter {
    21 
    22     @Override
    23     public void init(FilterConfig filterConfig) throws ServletException {
    24         System.out.println("time filter init2");
    25 
    26     }
    27 
    28     @Override
    29     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    30             throws IOException, ServletException {
    31         System.out.println("time filter start2");
    32         //进行下一个调用链
    33         long start=new Date().getTime();
    34         chain.doFilter(request, response);
    35         System.out.println("time filter2 耗时: "+(new Date().getTime()-start));
    36         System.out.println("time filter finish2");
    37 
    38     }
    39 
    40     @Override
    41     public void destroy() {
    42         System.out.println("time filter destroy2");
    43 
    44     }
    45 
    46 }

      新建一个包,为config

      新建一个类,为配置类

     1 package com.cao.web.config;
     2 
     3 
     4 import java.util.ArrayList;
     5 import java.util.List;
     6 
     7 import org.springframework.boot.web.servlet.FilterRegistrationBean;
     8 import org.springframework.context.annotation.Bean;
     9 import org.springframework.context.annotation.Configuration;
    10 
    11 import com.cao.web.filter.TimeFilter2;
    12 
    13 /**
    14  *  这里相当于在配置web.xml
    15  * @author dell
    16  */
    17 
    18 //说明这是一个配置类
    19 @Configuration
    20 public class WebConfig {
    21     @Bean
    22     public FilterRegistrationBean timeFilter2() {
    23         //加入Filter
    24         FilterRegistrationBean registrationBean=new FilterRegistrationBean();
    25         TimeFilter2 timeFilter2=new TimeFilter2();
    26         registrationBean.setFilter(timeFilter2);
    27         //起作用的url
    28         List<String> url=new ArrayList<>();
    29         url.add("/*");
    30         registrationBean.setUrlPatterns(url);
    31         //返回
    32         return registrationBean;
    33         
    34     }
    35 }

      启动

      

      访问

      

      发现,这里的服务只会走一次,外面包裹的是其过滤器的处理。

    三:拦截器

    1.过滤器的问题

      不知道是那个过滤器的哪个方法处理的。

      过滤器是Java EE提供的。

      拦截器是spring提供的。

      会拦截所有的控制器。

    2.新建一个interception的包

      新建TimeInterception的程序

     1 package com.cao.web.config;
     2 
     3 
     4 import java.util.ArrayList;
     5 import java.util.List;
     6 
     7 import org.springframework.beans.factory.annotation.Autowired;
     8 import org.springframework.boot.web.servlet.FilterRegistrationBean;
     9 import org.springframework.context.annotation.Bean;
    10 import org.springframework.context.annotation.Configuration;
    11 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    12 import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    13 
    14 import com.cao.web.filter.TimeFilter2;
    15 import com.cao.web.interceptor.TimeInterceptor;
    16 
    17 /**
    18  *  这里相当于在配置web.xml
    19  * @author dell
    20  */
    21 
    22 //说明这是一个配置类
    23 @Configuration
    24 public class WebConfig extends WebMvcConfigurerAdapter{
    25     
    26     //已经把TimeInterceptor变成了spring的一个组件了,现在需要autowired进来
    27     @Autowired
    28     private TimeInterceptor timeInterceptor;
    29     
    30     /**
    31      * 这里是拦截器
    32      */
    33     @Override
    34     public void addInterceptors(InterceptorRegistry registry) {
    35         registry.addInterceptor(timeInterceptor);
    36         super.addInterceptors(registry);
    37     }
    38     
    39     /**
    40      *   过滤器注册
    41      * @return
    42      */
    43     @Bean
    44     public FilterRegistrationBean timeFilter2() {
    45         //加入Filter
    46         FilterRegistrationBean registrationBean=new FilterRegistrationBean();
    47         TimeFilter2 timeFilter2=new TimeFilter2();
    48         registrationBean.setFilter(timeFilter2);
    49         //起作用的url
    50         List<String> url=new ArrayList<>();
    51         url.add("/*");
    52         registrationBean.setUrlPatterns(url);
    53         //返回
    54         return registrationBean;
    55 //        return null;
    56     }
    57 }

      配置类

        因为只有一个Component的注解不能是的拦截器像过滤器一样可以工作

     1 package com.cao.web.interceptor;
     2 
     3 import java.util.Date;
     4 
     5 import javax.servlet.http.HttpServletRequest;
     6 import javax.servlet.http.HttpServletResponse;
     7 
     8 import org.springframework.stereotype.Component;
     9 import org.springframework.web.method.HandlerMethod;
    10 import org.springframework.web.servlet.HandlerInterceptor;
    11 import org.springframework.web.servlet.ModelAndView;
    12 //使得成为Spring的组件
    13 @Component
    14 public class TimeInterceptor implements HandlerInterceptor {
    15 
    16     @Override
    17     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    18             throws Exception {
    19         System.out.println("preHandle init");
    20         //比过滤器的优势,有第三个参数,handler
    21         System.out.println("类:"+((HandlerMethod)handler).getBean().getClass().getName());
    22         System.out.println("方法:"+((HandlerMethod)handler).getMethod().getName());
    23         
    24         //朝请求里添加属性
    25         request.setAttribute("startTime", new Date().getTime());
    26         return true;
    27     }
    28 
    29     @Override
    30     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
    31             ModelAndView modelAndView) throws Exception {
    32         System.out.println("postHandle init");
    33         //处理
    34         Long start=(Long)request.getAttribute("startTime");
    35         System.out.println("postHandle time interceptor 耗时: "+(new Date().getTime()-start));
    36 
    37     }
    38 
    39     @Override
    40     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
    41             throws Exception {
    42         System.out.println("afterCompletion init");
    43     }
    44 
    45 }

      访问效果

      

    四:切片

    1.问题

      拦截器也有问题,不能拿到方法的具体参数。

      也是spring的核心功能之一,AOP

    2.步骤

      

    3.添加pom

    1 <dependency>
    2                 <groupId>org.springframework.boot</groupId>
    3             <artifactId>spring-boot-starter-aop</artifactId>
    4           </dependency>

    4.新建包

      aspect包。

    5.程序

      切片

     1 package com.cao.web.aspect;
     2 
     3 import java.util.Date;
     4 
     5 import org.aspectj.lang.ProceedingJoinPoint;
     6 import org.aspectj.lang.annotation.Around;
     7 import org.aspectj.lang.annotation.Aspect;
     8 import org.springframework.stereotype.Component;
     9 
    10 //切片
    11 @Aspect
    12 //成为spring容器的一部分
    13 @Component
    14 public class TimeAcpect {
    15     @Around("execution(* com.cao.web.controller.UserController.*(..))")
    16     public Object handleControlledrMethod(ProceedingJoinPoint pjp) throws Throwable {
    17         System.out.println("time aspect start");
    18         Object[] args=pjp.getArgs();
    19         for(Object arg : args) {
    20             System.out.println("args is "+arg);
    21         }
    22         //
    23         long start=new Date().getTime();
    24         Object object=pjp.proceed();
    25         System.out.println("time aspect 耗时: "+(new Date().getTime()-start));
    26         //
    27         System.out.println("time aspect end");
    28         
    29         return object;
    30     }
    31 }

      控制类

     1 @RequestMapping(value="/user/{id:\d+}",method=RequestMethod.GET)
     2     @JsonView(User.UserDetailView.class)
     3     @GetMapping(value="/{id:\d+}")
     4     public User getInfo(@PathVariable(value="id") String idid){
     5         /**
     6          *  演示filter调用
     7          */
     8         System.out.println("进入getInfo服务");
     9         
    10         System.out.println("idtt="+idid);
    11         User user=new User();
    12         user.setUsername("tom");
    13         return user;
    14         /**
    15          *  下面的主要是演示Spring booter异常的处理机制,现在先注释掉
    16          */
    17 //        throw new UserNotExistException(idid);
    18         
    19     }

    6.效果

      访问

      

      控制台:

      

    五:先后之行顺序

    1.顺序

      上完上面的示例,应该没有问题了,这里使用一个图做一个总结。

      具体的文字就不再描述了,不懂的话,可以看上面的控制台效果

      

      

  • 相关阅读:
    2015百度之星 放盘子
    2015百度之星 IP聚合
    2015百度之星 列变位法解密
    2015百度之星 大搬家
    数论 --- 费马小定理 + 快速幂 HDU 4704 Sum
    组合数(Lucas定理) + 快速幂 --- HDU 5226 Tom and matrix
    Linux
    概率论 --- Uva 11181 Probability|Given
    JAVA
    网络爬虫-原理篇(二)
  • 原文地址:https://www.cnblogs.com/juncaoit/p/9721378.html
Copyright © 2011-2022 走看看