filter
新建 timefilter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
@component 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 starttime = system.currenttimemillis();
filterchain.dofilter(servletrequest, servletresponse);
long endtime = system.currenttimemillis(); system.out.println( "time filter consume " + (endtime - starttime) + " ms" ); system.out.println( "time filter end" ); }
@override public void destroy() { system.out.println( "time filter init" ); } } |
启动服务器,在浏览器输入:http://localhost:8080/hello?name=tom
可以在控制台输出如下结果:
time filter start
name: tom
time filter consume 3 ms
time filter end
可以看到,filter 先执行,再到真正执行 hellocontroller.sayhello() 方法。
通过 timefilter.dofilter(servletrequest servletrequest, servletresponse servletresponse, filterchain filterchain) 方法的参数可以看出,我们只能得到原始的 request 和 response对象,不能得到这个请求被哪个 controller 以及哪个方法处理了,使用interceptor 就可以获得这些信息。
interceptor
新建 timeinterceptor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
@component public class timeinterceptor extends handlerinterceptoradapter {
private final namedthreadlocal< long > starttimethreadlocal = new namedthreadlocal<>( "starttimethreadlocal" );
@override public boolean prehandle(httpservletrequest request, httpservletresponse response, object handler) throws exception { system.out.println( "time interceptor prehandle" );
handlermethod handlermethod = (handlermethod) handler; // 获取处理当前请求的 handler 信息 system.out.println( "handler 类:" + handlermethod.getbeantype().getname()); system.out.println( "handler 方法:" + handlermethod.getmethod().getname());
methodparameter[] methodparameters = handlermethod.getmethodparameters(); for (methodparameter methodparameter : methodparameters) { string parametername = methodparameter.getparametername(); // 只能获取参数的名称,不能获取到参数的值 //system.out.println("parametername: " + parametername); }
// 把当前时间放入 threadlocal starttimethreadlocal.set(system.currenttimemillis());
return true ; }
@override public void posthandle(httpservletrequest request, httpservletresponse response, object handler, modelandview modelandview) throws exception { system.out.println( "time interceptor posthandle" ); }
@override public void aftercompletion(httpservletrequest request, httpservletresponse response, object handler, exception ex) throws exception {
// 从 threadlocal 取出刚才存入的 starttime long starttime = starttimethreadlocal.get(); long endtime = system.currenttimemillis();
system.out.println( "time interceptor consume " + (endtime - starttime) + " ms" );
system.out.println( "time interceptor aftercompletion" ); } } |
注册 timeinterceptor
把 timeinterceptor 注入 spring 容器
1 2 3 4 5 6 7 8 9 10 11 |
@configuration public class webconfig extends webmvcconfigureradapter {
@autowired private timeinterceptor timeinterceptor;
@override public void addinterceptors(interceptorregistry registry) { registry.addinterceptor(timeinterceptor); } } |
启动服务器,在浏览器输入:http://localhost:8080/hello?name=tom
可以在控制台输出如下结果:
1 2 3 4 5 6 7 8 9 10 |
time filter start time interceptor prehandle handler 类:com.nextyu.demo.web.controller.hellocontroller handler 方法:sayhello name: tom time interceptor posthandle time interceptor consume 40 ms time interceptor aftercompletion time filter consume 51 ms time filter end |
可以看到,filter 先于 interceptor 执行,再到真正执行 hellocontroller.sayhello() 方法。通过 interceptor 方法上的 handler 参数,我们就可以得到这个请求被哪个 controller 以及哪个方法处理了。但是不能直接获取到这个方法上的参数值(在这里就是 hellocontroller.sayhello(string name) 方法参数 name 的值),通过 aspect 就可以获取到。
aspcet
新建 timeaspect
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
@aspect @component public class timeaspect {
@around ( "execution(* com.nextyu.demo.web.controller.*.*(..))" ) public object handlecontrollermethod(proceedingjoinpoint pjp) throws throwable {
system.out.println( "time aspect start" );
object[] args = pjp.getargs(); for (object arg : args) { system.out.println( "arg is " + arg); }
long starttime = system.currenttimemillis();
object object = pjp.proceed();
long endtime = system.currenttimemillis(); system.out.println( "time aspect consume " + (endtime - starttime) + " ms" );
system.out.println( "time aspect end" );
return object; }
} |
启动服务器,在浏览器输入:http://localhost:8080/hello?name=tom
可以在控制台输出如下结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
time filter start time interceptor prehandle handler 类:com.nextyu.demo.web.controller.hellocontroller handler 方法:sayhello time aspect start arg is tom name: tom time aspect consume 0 ms time aspect end time interceptor posthandle time interceptor consume 2 ms time interceptor aftercompletion time filter consume 4 ms time filter end |
可以看到,filter 先执行,再到 interceptor 执行,再到 aspect 执行,再到真正执行 hellocontroller.sayhello() 方法。
我们也获取到了 hellocontroller.sayhello(string name) 方法参数 name 的值。
请求拦截过程图
1 2 3 4 5 |
graph td httprequest-->filter filter-->interceptor interceptor-->aspect aspect-->controller |
查看更多关于详解java中spring里的三大拦截器的详细内容...