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.順序
上完上面的示例,應該沒有問題了,這里使用一個圖做一個總結。
具體的文字就不再描述了,不懂的話,可以看上面的控制臺效果
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的008 RestFul API 拦截器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 64位win10系统无法安装.Net f
- 下一篇: 相邻兄弟选择器(+)、子选择器()、兄弟