这三种拦截方式的拦截顺序是:filter—>Interceptor-->ControllerAdvice-->@Aspect -->Controller;
这三种方式的区陪昌别:
1.过滤器Filter可以拿到原始的HTTP请求和响应的信息, 但是拿不到你真正处理请求方法的信芦此扒息,也就是方法的信息。
2.拦截扒型器Interceptor可以拿到原始的HTTP请求和响应的信息,也可以拿到你真正处理请求方法的信息,但是拿不到传进参数的那个值。
3.切片Aspect,既然Spring那么支持AOP,可以拿到原始的HTTP请求和响应的信息, 也可以拿到你真正处理请求方法的信息,也可以传进参数的那个值。
实现Filter接口
实现 HandlerInterceptor 接口,然后配置进Spring。
配置进spring
pom.xml 添加Aop支持
在Java的服务端开发当中,拦截器是很常见的业务场景,这里对Java开发当中几种常见的拦截器的实现方式进行记喊悔录和分析。案例说明基于Spring Boot环境。一:实现javax.servlet.Filter接口(使用过滤器方式拦截请求)
import org.springframework.stereotype.Componentimport javax.servlet.*import java.io.IOExceptionimport java.util.Date@Componentpublic class TimeInterceptor implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("time filter init")}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("time filter start")long start = new Date().getTime()filterChain.doFilter(servletRequest, servletResponse)System.out.println("time filter 耗时:"+(new Date().getTime()-start))System.out.println("time filter finish")}@Overridepublic void destroy() {System.out.println("time filter destroy")}}
如使用@Compent注解声明不需要加入其它配置即可使得拦截器生效,但是默认拦截/*,会拦截告渗誉所有请求。
二:使用@Bean注入自定义拦截器,依然上面的代码,去掉@Compent注解,创建TimeWebConfig配置类:
import org.springframework.boot.web.servlet.FilterRegistrationBeanimport org.springframework.context.annotation.Beanimport org.springframework.context.annotation.Configurationimport java.util.ArrayListimport java.util.List@Configurationpublic class TimeWebConfig {@Beanpublic FilterRegistrationBean timeFilter(){FilterRegistrationBean registrationBean = new FilterRegistrationBean()TimeInterceptor interceptor = new TimeInterceptor()registrationBean.setFilter(interceptor)List<String>urls = new ArrayList<>()urls.add("/user/*")registrationBean.setUrlPatterns(urls)return registrationBean}}
上面这两种拦截请求的实现是基于JavaEE提供的Filter接口实现的,缺点在于,该拦截器实际上是一个过滤器,执行代码的方法doFilter只提供了request,response等参数,当请求进入被过滤器拦截的时候,我们袜段并不知道这个请求是由哪个控制器的哪个方法来执行的。
三:使用springMVC提供的拦截器,实现org.springframework.web.servlet.HandlerInterceptor接口:
创建自定义的拦截器:
import org.springframework.stereotype.Componentimport org.springframework.web.method.HandlerMethodimport org.springframework.web.servlet.HandlerInterceptorimport org.springframework.web.servlet.ModelAndViewimport javax.servlet.http.HttpServletRequestimport javax.servlet.http.HttpServletResponseimport java.util.Date@Componentpublic class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) throws Exception {System.out.println("preHandler")System.out.println(((HandlerMethod) handler).getBean().getClass().getName())System.out.println(((HandlerMethod) handler).getMethod().getName())httpServletRequest.setAttribute("start", new Date().getTime())return true}@Overridepublic void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {System.out.println("postHandler")Long start = (Long) httpServletRequest.getAttribute("start")System.out.println("time interceptor 耗时:"+(new Date().getTime()-start))}@Overridepublic void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {System.out.println("afterCompletion")Long start = (Long) httpServletRequest.getAttribute("start")System.out.println("time interceptor 耗时:"+(new Date().getTime()-start))System.out.println("ex is:"+e)}}
创建配置类:
import org.springframework.beans.factory.annotation.Autowiredimport org.springframework.context.annotation.Configurationimport org.springframework.web.servlet.config.annotation.InterceptorRegistryimport org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter@Configurationpublic class WebConfig extends WebMvcConfigurerAdapter {@Autowiredprivate MyInterceptor interceptor@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(interceptor).addPathPatterns("/user/*").excludePathPatterns("/blog/*")}}
此种方式的拦截器当中我们能够获取拦截的请求对应的类和方法的相关信息,缺点在于该handler对象无法获取具体执行方法的参数信息。
四:利用Spring的切面(AOP)实现拦截器:
引入jar包:
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>
创建切片类:
import org.aspectj.lang.ProceedingJoinPointimport org.aspectj.lang.annotation.Aroundimport org.aspectj.lang.annotation.Aspectimport org.springframework.stereotype.Componentimport java.util.Date@Aspect@Componentpublic class TimeAspect {@Around("execution(* com.qinker.controller.UserController.*(..))")public Object handlerControllerMethod(ProceedingJoinPoint point) throws Throwable {System.out.println("time aspect start")long start = new Date().getTime()Object[] args = point.getArgs()for (Object obj : args) {System.out.println("arg is:"+obj)}Object obj = point.proceed()//具体方法的返回值System.out.println("aspect 耗时:"+(new Date().getTime()-start))System.out.println("time aspect end")return obj}}
aspectj基于AOP实现的拦截器功能十分强大,具体详解请参考spring官网网站的文档。
方法/步骤打开浏览器,点击浏览谈滑器菜单栏,找到“工具”点击 Internet选项,设置浏览器代理地址为127.0.0.1,端口8080
打开burpsuite确定设置的代理地址与浏览器一致。
打键芦开浏览器,打开一个网页,会看到打开的网页浏览记录都经过了burpsuite。
当Intercept is on时,表示已经开启拦截功能。
在网站可输入的地方,例如搜索,输入“2015”,开启burpsuite拦截功能,可看到为post请求,最后面的就是提交的数据。
右键选择send to repeater或者快捷键ctrl+r 把拦截的数据包到repeater项中,直接修改数据,如把原本要搜索的项“2015”改为“2016”,点击go来提交,那么响应回来的数据就是改修后的页面和信息。(burpsuite的抓包,拦截,修含亮腊改)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)