攔截器功能強大,能夠深入方法前后,常應用于日志記錄、權限檢查和性能檢測等,幾乎是項目中不可或缺的一部分,本文就來實現spring boot自定義攔截器的配置。
理論指導
問:spring boot怎么配置攔截器?
答:配置一個攔截器需要兩步完成。
- 自定義攔截器,實現handlerinterceptor這個接口。這個接口包括三個方法,prehandle是請求執行前執行的,posthandler是請求結束執行的,但只有prehandle方法返回true的時候才會執行,aftercompletion是視圖渲染完成后才執行,同樣需要prehandle返回true,該方法通常用于清理資源等工作。
- 注冊攔截器。 作用是確定攔截器和攔截的url。需要繼承webmvcconfigurationsupport并重寫addinterceptor方法,webmvcconfigureadapter已經過時了!!
代碼實現
目錄結構:
具體代碼:
myinterceptor.java
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
|
public class myinterceptor implements handlerinterceptor { /** * prehandle在執行controller之前執行,返回true,則繼續執行contorller * 返回false則請求中斷。 */ @override public boolean prehandle(httpservletrequest httpservletrequest, httpservletresponse httpservletresponse, object o) throws exception { //只有返回true才會繼續向下執行,返回false取消當前請求 long starttime = system.currenttimemillis(); httpservletrequest.setattribute( "starttime" , starttime); return true ; } /** * posthandle是在請求執行完,但渲染modelandview返回之前執行 */ @override public void posthandle(httpservletrequest httpservletrequest, httpservletresponse httpservletresponse, object o, modelandview modelandview) throws exception { long starttime = ( long ) httpservletrequest.getattribute( "starttime" ); long endtime = system.currenttimemillis(); long executetime = endtime - starttime; stringbuilder sb = new stringbuilder( 1000 ); simpledateformat simpledateformat = new simpledateformat( "yyyy-mm-dd hh:mm:ss" ); string date = simpledateformat.format( new date()); sb.append( "-----------------------" ).append(date).append( "-------------------------------------\n" ); sb.append( "uri : " ).append(httpservletrequest.getrequesturi()).append( "\n" ); sb.append( "costtime : " ).append(executetime).append( "ms" ).append( "\n" ); sb.append( "-------------------------------------------------------------------------------" ); system.out.println(sb.tostring()); } /** * aftercompletion是在整個請求執行完畢后執行 */ @override public void aftercompletion(httpservletrequest httpservletrequest, httpservletresponse httpservletresponse, object o, exception e) throws exception { } } |
registerinterceptor.java
1
2
3
4
5
6
7
8
9
10
11
12
|
/** * 繼承webmvcconfigurationsupport繼承并重寫addinterceptor方法用于注冊攔截器 * webmvcconfigureadapter已經過時了!! */ @configuration public class registerinterceptor extends webmvcconfigurationsupport { @override public void addinterceptors(interceptorregistry registry) { registry.addinterceptor( new myinterceptor()).addpathpatterns( "/**" ); super .addinterceptors(registry); } } |
攔截效果
更新
跨域訪問
由于javascript同源策略,凡是發送請求url的協議、域名、端口三者之間任意一與當前頁面地址不同即為跨域。具體的看下表
url
|
說明
|
是否允許通信
|
http://www.a.com/a.js
http://www.a.com/b.js
|
同一域名下
|
允許
|
http://www.a.com/lab/a.js
http://www.a.com/script/b.js
|
同一域名下不同文件夾
|
允許
|
http://www.a.com:8000/a.js
http://www.a.com/b.js
|
同一域名,不同端口
|
不允許
|
http://www.a.com/a.js
https://www.a.com/b.js
|
同一域名,不同協議
|
不允許
|
http://www.a.com/a.js
http://70.32.92.74/b.js
|
域名和域名對應ip
|
不允許
|
http://www.a.com/a.js
http://script.a.com/b.js
|
主域相同,子域不同
|
不允許
|
http://www.a.com/a.js
http://a.com/b.js
|
同一域名,不同二級域名(同上)
|
不允許(cookie這種情況下也不允許訪問)
|
http://www.cnblogs.com/a.js
http://www.a.com/b.js
|
不同域名
|
不允許
|
上面代碼是可以實現攔截器基本功能,但是這樣是不可以跨域訪問的,前端請求接口會有報錯:xmlhttprequest cannot loadhttp://xxx/. no 'access-control-allow-origin' header is present on the requested resource. origin 'null' is therefore not allowed access.
解決方案是設置請求頭access-control-allow-origin為“*”或者設置為和request相同的origin。
①在攔截器中添加一個設置請求頭的方法。
1
2
3
4
|
public void crossdomain(httpservletrequest request, httpservletresponse response) { response.setheader( "access-control-allow-origin" , request.getheader( "origin" )); response.setheader( "access-control-allow-credentials" , "true" ); } |
②在prehandle中調用這個方法。
1
2
3
4
5
6
7
|
public boolean prehandle(httpservletrequest request, httpservletresponse response, object handler) throws exception { crossdomain(request, response); long starttime = system.currenttimemillis(); request.setattribute( "starttime" , starttime); return true ; } |
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://www.cnblogs.com/sgh1023/p/10056859.html