1, Introduction to the interceptor
public interface HandlerInterceptor {
boolean preHandle(
HttpServletRequest request, HttpServletResponse response,
Object handler)
throws Exception;
void postHandle(
HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView)
throws Exception;
void afterCompletion(
HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex)
throws Exception;
}
preHandle: Preparatory processing method to implement the processor’s pre -processing (such as login check), the third parameter is the processor of the response (such as the implementation of the controller in the previous chapter);
Return value: TRUE represents the continuing process (such as calling the next interceptor or processor);
FALSE indicates that the process is interrupted (if the login check failed), it will not continue to call other interceptors or processors. At this time, we need to use Response to generate a response;
postHandle: post -processing method to realize the post -processing of the processor (but before rendering the view), at this time we can process the model data through the ModratView (model and view object), and the model may also be null.
afterCompletion:The entire request processing method is completed, that is, when the view rendering is completed, if we can record the end time and output the time in the performance monitoring, it can also be cleaned up, similar to the final of the TRY-Catch-Finally. , But only call the processor execute chain
2, run flow chart
normal process
During the interruption process, such as the process of handlerinterceptor4 interrupt (Prehandle returns false), here only call it the previous interceptor (HandlerInterceptor3) The PreHAndle returns True’s Aftercompleting method.
three, instance entry
Question:
Our interceptor is a single case, so no matter how many times the user requests, there is only one interceptor implementation, that is, the thread is not safe, so how should we record time?
The
solution is using ThreadLocal, which is a variable binding of threads, providing local variables of the thread (one thread, one threadLocal, threads ThreadLocal can only see threads ThreadLocal.
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.NamedThreadLocal;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class StopWatchHandlerInterceptor extends HandlerInterceptorAdapter {
private NamedThreadLocal<Long> startTimeThreadLocal=
new NamedThreadLocal<Long>("StopWatch-stratTime");
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
// TODO Auto-generated method stub
long beginTime =System.currentTimeMillis();
startTimeThreadLocal.set(beginTime);
return true;
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// TODO Auto-generated method stub
long endTime=System.currentTimeMillis();
long beginTime=startTimeThreadLocal.get();
long consumeTime =endTime - beginTime;
System.out.println("123"+
String.format("%s consume %d millis", request.getRequestURI(),consumeTime));
}
}
***-Service.xml configuration
<!-Interceptor->
<MVC: interceptors>
<MVC: interceptor>
<MVC: MAPPING PATH = "/Test"/>
<bean class = "com.cn.main.stopwatchhandlerInterceptor"> </bean>
</mvc: interceptor>
</mvc: interceptors>
URL is test, start the interceptor under the corresponding path