可以偷偷利用 LoggingFilter 作為攔截的手段。
首先要利用 LogginFilter 之前,需要先寫一個自定義的 Filter,這裡就仿照 [1] 的網友 markthegrea 提供的範例:
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 |
package example; import java.util.Calendar; import com.sun.jersey.api.container.filter.LoggingFilter; import com.sun.jersey.spi.container.ContainerRequest; import com.sun.jersey.spi.container.ContainerRequestFilter; import com.sun.jersey.spi.container.ContainerResponse; public class RequestLogger extends LoggingFilter implements ContainerRequestFilter { private static ThreadLocal<Long> EXECUTION_TIME = new ThreadLocal<Long>(); @Override public ContainerRequest filter(ContainerRequest request) { EXECUTION_TIME.set(Calendar.getInstance().getTimeInMillis()); System.out.println( "Request is started at " + EXECUTION_TIME.get().longValue()); return request; } @Override public ContainerResponse filter(ContainerRequest request, ContainerResponse response) { StringBuilder sb = new StringBuilder(); sb.append( "User:" ).append((request.getUserPrincipal() == null ? "unknown" : request.getUserPrincipal().getName())); sb.append( " - Path:" ).append(request.getRequestUri().getPath()); sb.append( " - " ).append(Calendar.getInstance().getTimeInMillis() - EXECUTION_TIME.get().longValue()); System.out.println(sb.toString()); return response; } } |
以上的程式碼有兩個覆寫 filter() 的方法,其實兩個方法分別對應的是不同的事件
上面的 filter(ContainerRequest) 是攔截 Request 收到的時間
而下面的 filter(ContainerRequest, ContainerResponse) 則是攔截 Response 送出的時間。
另外簡單說明一下,第一個攔截 Request 的 filter,做的事情就是在 console 中印出收到 Request 的時間。
而第二個攔截 Response 的 filter 則是依照收到 Request 的時間,去計算出這次 Request 總共花費的時間。
在定義好 LoggingFilter 之後,必須在 web.xml 上宣告 Request 和 Response 的 filter,伺服器在啟動時才知道要去哪裡執行攔截的動作。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
< servlet > < servlet-name >ServletAdaptor</ servlet-name > < servlet-class >com.sun.jersey.server.impl.container.servlet.ServletAdaptor</ servlet-class > < init-param > < param-name >com.sun.jersey.spi.container.ContainerRequestFilters</ param-name > < param-value >example.RequestLogger</ param-value > </ init-param > < init-param > < param-name >com.sun.jersey.spi.container.ContainerResponseFilters</ param-name > < param-value >example.RequestLogger</ param-value > </ init-param > < load-on-startup >1</ load-on-startup > </ servlet > |
上面的 XML 只包含關鍵的片段 XML,第 2 行開始是宣告 Jersey 的 Servlet。
其中 4~7 行是宣告 Request 的 filter、8~11 行是宣告 Response 的 filter
因為前面把 Request 和 Response 的 filter 都寫在同一個類別裡,所以這裡的 param-value 都指向同一個 class。
最後執行任意一個 RESTful 服務時,會看到以下的 console 訊息。
1 2 |
Request is started at 1377443204176 User:unknown - Path:/Jersey/web/test/test - 5 |
test/test 則是我測試時呼叫的 RESTful 服務。
參考資料:
1、How does one intercept a request during the Jersey lifecycle?
沒有留言:
張貼留言