目录结构: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地址