如 果您在 Controller 执行的前后,或者是在 View 绘制之后打算作一些记录或栏截请求等动作, 您可以实作 org.springframework.web.servlet.HandlerInterceptor 介面,在这个介面中规范了三个 必须实作的方法, 其定义如下所示:
package org.springframework.web.servlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; 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; }
preHandler()会在Controller处理请求之前被呼叫,传回的boolean快定是否呼叫接下来的Handler Interceptor或是Controller来处理请求,如果传回false,则接下来的Interceptor或Controller就不处 理请 求,postHandler()则会在Controller处理完请求之后被呼叫,afterCompletion()方法会在View 绘制完成之后被呼 叫。
您可以直接继承org.springframework.web.servlet.handler.HandlerInterceptorAdapter ,它实作了 HandlerInterceptor介面,您只要针对您有兴趣的方法进行重新定义就可以了,例如可以修改 第 一个 Spring MVC 程式,在当中实作一个LoggingInterceptor,在请求被控制物件处理的前、后来 作记录:
package onlyfun.caterpillar; import java.util.logging.Logger; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet. handler.HandlerInterceptorAdapter; public class LoggingInterceptor extends HandlerInterceptorAdapter { private Logger logger = Logger.getLogger(this.getClass().getName()); public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { logger.info(handler.getClass().getName() + " 开始执行..."); return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { logger.info(handler.getClass().getName() + " 执行完毕..."); } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { logger.info("请求处理完毕..."); } }
要使用定义好的 HandlerInterceptor,必须在 Bean 定义档中进行定义,例如:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN""http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="loggingInterceptor" class="onlyfun.caterpillar.LoggingInterceptor"/> <bean id="viewResolver" class="org.springframework.web.servlet. → view.InternalResourceViewResolver"> <property name="prefix"> <value>/WEB-INF/jsp/</value> </property> <property name="suffix"> <value>.jsp</value> </property> </bean> <bean id="urlHandlerMapping" class="org.springframework.web.servlet. → handler.SimpleUrlHandlerMapping"> <property name="interceptors"> <list> <ref bean="loggingInterceptor"/> </list> </property> <property name="mappings"> <props> <prop key="/hello.do">helloController</prop> </props> </property> </bean> <bean id="helloController" class="onlyfun.caterpillar.HelloController"> <property name="viewPage"> <value>hello</value> </property> </bean> </beans>
注意到这边所使用的 UrlHandlerMapping 是 SimpleUrlHandlerMapping;当您透过 DispatcherServlet 请求时,则在请求被处理的前后都会被记录下动作及所处理请求的控制物件,在控制台所看到的 资讯如下所示:
2005/12/30 上 午 12:03:24 onlyfun.caterpillar.LoggingInterceptor preHandle
资讯: onlyfun.caterpillar.HelloController 开始执行...
2005/12/30 上 午 12:03:24 onlyfun.caterpillar.LoggingInterceptor postHandle
资讯: onlyfun.caterpillar.HelloController 执行完毕...
2005/12/30 上 午 12:03:24 onlyfun.caterpillar.LoggingInterceptor afterCompletion