有時(shí)候我們要記錄下所有的http請(qǐng)求信息(請(qǐng)求的方法链烈,比如GET
憎茂;請(qǐng)求的uri,比如/api/v1/users
等信息)忍捡,在spring框架下集漾,很容易實(shí)現(xiàn)這個(gè)需求。
在spring框架下砸脊,用戶(hù)可以自定義web請(qǐng)求處理前后的攔截器具篇,其中HandlerInterceptor
接口是我們可以利用的。這個(gè)接口定義了3個(gè)函數(shù):我們只需要實(shí)現(xiàn)這3個(gè)接口凌埂,就可以攔截到所有的web請(qǐng)求信息驱显。
具體做法:
- 編寫(xiě)
HandlerInterceptor
實(shí)現(xiàn)類(lèi),重寫(xiě)其中的方法侨舆,這里重寫(xiě)了方法postHandle
秒紧,這個(gè)調(diào)用是在web請(qǐng)求成功處理后被調(diào)用。
public class PlatformRequestInterceptor implements HandlerInterceptor {
@Autowired
private PlatformAccessLogRepository repository;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//這里沒(méi)有直接讀取request對(duì)象挨下,而是通過(guò)`ContentCachingRequestWrapper`類(lèi)先進(jìn)行一次緩存熔恢,原因參考參考文檔[1]
HttpServletRequest requestCacheWrapperObject
= new ContentCachingRequestWrapper(request);
requestCacheWrapperObject.getParameterMap();
String uri = requestCacheWrapperObject.getRequestURI();
if (!uri.equals("/error")) {
String method = requestCacheWrapperObject.getMethod();
String userName = "guest";
if (requestCacheWrapperObject.getUserPrincipal() != null) {
userName = requestCacheWrapperObject.getUserPrincipal().getName();
}
String remoteAddr = requestCacheWrapperObject.getRemoteAddr();
PlatformAccessLog accessLog = new PlatformAccessLog();
accessLog.setMethod(method);
accessLog.setName(userName);
accessLog.setPath(uri);
accessLog.setTime(new Date());
accessLog.setRemoteAddr(remoteAddr);
repository.insert(accessLog);
}
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}
- 注冊(cè)上面寫(xiě)好的攔截器實(shí)現(xiàn),重載
WebMvcConfigurerAdapter
的addInterceptors
方法臭笆。
@Configuration
public class PlatformMVCConfig extends WebMvcConfigurerAdapter {
@Autowired
private HandlerInterceptor interceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(interceptor);
}
}
經(jīng)過(guò)上面的操作叙淌,就可以把所有正常處理的http請(qǐng)求記錄到mongodb中了。寫(xiě)入數(shù)據(jù)庫(kù)的代碼略愁铺。