目錄結構:javascript
TimeCostInterceptor是一個功能齊全的攔截器,須要用到util裏面的工具類,因爲代碼較多,感興趣的能夠到GitHub中查看源碼。html
具體代碼:前端
MyInterceptor.javajava
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.javagit
/** * 繼承WebMvcConfigurationSupport繼承並重寫addInterceptor方法用於註冊攔截器 * WebMvcConfigureAdapter已通過時了!! */ @Configuration public class RegisterInterceptor extends WebMvcConfigurationSupport { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**"); super.addInterceptors(registry); } }
更新github
因爲JavaScript同源策略,凡是發送請求url的協議、域名、端口三者之間任意一與當前頁面地址不一樣即爲跨域。具體的看下錶(來源於javascript跨域資源總結與解決辦法):spring
URL
|
說明
|
是否容許通訊
|
同一域名下
|
容許
|
|
同一域名下不一樣文件夾
|
容許
|
|
同一域名,不一樣端口
|
不容許
|
|
同一域名,不一樣協議
|
不容許
|
|
域名和域名對應ip
|
不容許
|
|
主域相同,子域不一樣
|
不容許
|
|
同一域名,不一樣二級域名(同上)
|
不容許(cookie這種狀況下也不容許訪問)
|
|
不一樣域名
|
不容許
|
上面代碼是能夠實現攔截器基本功能,可是這樣是不能夠跨域訪問的,前端請求接口會有報錯: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。cookie
①在攔截器中添加一個設置請求頭的方法。app
public void crossDomain(HttpServletRequest request, HttpServletResponse response) { response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin")); response.setHeader("Access-Control-Allow-Credentials", "true"); }
②在preHandle中調用這個方法。
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { crossDomain(request, response); long startTime = System.currentTimeMillis(); request.setAttribute("startTime", startTime); return true; }
完整代碼:GItHub地址