学习笔记 Spring 常用拦截器 我将以记录访问EESTFul API 访问者的ip地址为例 常见的三种拦截机制是实现以下三种实现的 1.过滤器 Filter 2.拦截器 Interceptor 3.切片Aspect 先让我们写一个简单的Filter 但是还是会有一些需要使我们不得应用启动项目的组件,那如何做到这一步了 这里我不找其他的过滤器我就用我写的Filter做Demo //@Component 注释掉 public class IpFilter implements Filter @Configuration public class FilterConfig { @Bean public FilterRegistrationBean IpFilter(){ //声明FilterRegistrationBean FilterRegistrationBean registrationBean=new FilterRegistrationBean(); //声明IpFilter 第三方Filter IpFilter ipFilter=new IpFilter(); registrationBean.setFilter(ipFilter); //设置拦截路径 List<String> url=new ArrayList<>(); //all url.add("/*"); registrationBean.setUrlPatterns(url); return registrationBean; } } Filter是可以拿到request,responst,但是他是不知道是哪个contrllor 哪个方法传过来的
/**
* createUser:JAVA_TOM
* FileName: IpFilter
* Author: 14562
* Date: 2018/11/4 13:22
* Description: Filter
*/
package com.zwl.security.demo.filter;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
//实现javax.servlet.Filter
public class IpFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//初始化Filter
System.out.println("my filtr init");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//业务代码
System.out.println("my filtr start");
HttpServletRequest reque = (HttpServletRequest)request;//;
String ipString =reque.getHeader("x-forwarded-for");
if (StringUtils.isBlank(ipString) || "unknown".equalsIgnoreCase(ipString))
{ ipString = reque.getHeader("Proxy-Client-IP"); }
if (StringUtils.isBlank(ipString) || "unknown".equalsIgnoreCase(ipString))
{ ipString = reque.getHeader("WL-Proxy-Client-IP"); }
if (StringUtils.isBlank(ipString) || "unknown".equalsIgnoreCase(ipString))
{ ipString = reque.getRemoteAddr(); }
System.out.println(ipString);
chain.doFilter(request,response);//业务代码处理完毕执行后续代码
System.out.println("my filtr finish");
}
@Override
public void destroy() {
//销毁Filter
System.out.println("my filtr destroy");
}
}
但是用Interceptor可以解决
/**
* createUser:JAVA_TOM
* FileName: IpInterceptor
* Author: 14562
* Date: 2018/11/4 19:32
* Description: Interceptor
*/
package com.zwl.security.demo.interceptor;
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 IpInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//在进contrllor的末个方法调用
System.out.println("my IpInterceptor preHandle");
System.out.println(((HandlerMethod)handler).getBean().getClass().getName());
System.out.println(((HandlerMethod)handler).getMethod().getName());
request.setAttribute("time",new Date().getTime());
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("my IpInterceptor postHandle");
Long time=(Long)request.getAttribute("time");
System.out.println("耗时=》"+(new Date().getTime()-time));
//在进入方法执行。但是调用的方法出现了异常,就不会调用
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("my IpInterceptor afterCompletion");
//后执行,多会执行
//这里由于有个Exception,所以我们可以对这里做一些Exception的处理
}
}
@Configuration public class WebConfig extends WebMvcConfigurerAdapter { @Autowired private IpInterceptor ipInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(ipInterceptor); } } 最终执行的结果 my IpInterceptor preHandle org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController errorHtml my IpInterceptor preHandle com.zwl.security.demo.controller.userController hello 如果我们还想拿到传参,那么就需要用切片 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 IpAspect { //Around中的表达式不会请访问这个网址 //https://docs.spring.io/spring/docs/4.3.21.BUILD-SNAPSHOT/spring-framework-reference/htmlsingle/#aop-pointcuts @Around("execution(* com.zwl.security.demo.controller.userController.*(..))") public Object handleControllerMethod(ProceedingJoinPoint pjp) throws Throwable { System.out.println("my IpAspect start"); long start=System.currentTimeMillis(); Object[] args=pjp.getArgs(); for(Object arg : args){ System.out.println("start =>"+arg); } Object object=pjp.proceed(); System.out.println("time=>"+(System.currentTimeMillis()-start)); System.out.println("my IpAspect end"); ; return null; } } 总结的以上几种问题,我们来谈谈着三种的执行速度 我通过打印得到 1.Filter 2.Interseptor 3.controllerAdvice 4.Aspect 5.controller