Spring MVC支持配置多個攔截器,http請求將被配置的攔截器處理,處理後報錯信息拋異常,異常將被DispatcherServlet捕獲處理,每個攔截器對應的handler處理異常,包裝成ModelAndView返回。
web.xml 配置
<servlet>
<servlet-name>myservlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>springConfiguration</param-name>
<param-value>classpath:conf/spring-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
DispatcherServlet配置好了主要處理各種前端的Http請求分派。
spring-config.xml 配置
<mvc:interceptor>
<mvc:mapping path="/restful/**"/>
<bean class="com.baobao.interceptor.ParamValidationInterceptor">
<property name="localValidatorFactoryBean" ref="validator"></property>
</bean>
</mvc:interceptor>
在該配置文件中可以配置bean的加載(例如可以用掃描包路徑的方式),各種攔截器、校驗器、Job等。
這次以restful請求的參數校驗爲例,說明攔截器的使用。攔截器必須實現HandlerInterceptor接口,該接口有三個方法,一般實現preHandle方法即可。
public class ParamValidationInterceptor implements HandlerInterceptor, InitializingBean {
private LocallocalValidatorFactoryBean localValidatorFactoryBean;
/**
* Invoked by a BeanFactory after it has set all bean properties supplied
* (and satisfied BeanFactoryAware and ApplicationContextAware).
* <p>This method allows the bean instance to perform initialization only
* possible when all bean properties have been set and to throw an
* exception in the event of misconfiguration.
*
* @throws Exception in the event of misconfiguration (such
* as failure to set an essential property) or if initialization fails.
*/
@Override
public void afterPropertiesSet() throws Exception {
}
/**
* Intercept the execution of a handler. Called after HandlerMapping determined
* an appropriate handler object, but before HandlerAdapter invokes the handler.
* <p>DispatcherServlet processes a handler in an execution chain, consisting
* of any number of interceptors, with the handler itself at the end.
* With this method, each interceptor can decide to abort the execution chain,
* typically sending a HTTP error or writing a custom response.
*
* @param request current HTTP request
* @param response current HTTP response
* @param handler chosen handler to execute, for type and/or instance evaluation
* @return <code>true</code> if the execution chain should proceed with the
* next interceptor or the handler itself. Else, DispatcherServlet assumes
* that this interceptor has already dealt with the response itself.
* @throws Exception in case of errors
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if(! (handler instanceof HandlerMethod)) {
return true;
}
HandlerMethod method = (HandlerMethod) handler;
MethodParameter[] parameters = method.getMethodParameters();
Object[] parameterArray = new Object[parameters.length];
ValidatorImpl validatorImpl = (ValidatorImpl) localValidatorFactoryBean.getValidator();
Annotation[][] annotations = method.getMethod().getParameterAnnotations();
for (int i = 0; i < annotations.length; i++) {
for (int j = 0; j < annotations[i].length; j++) {
if (annotations[i][j] instanceof RequestParam) {
String key = ((RequestParam) annotations[i][j]).value();
parameterArray[i] = request.getParameter(key);
}
}
}
Set<MethodConstraintViolation<Object>> errInfoSet
= validatorImpl.validateAllParameters(method.getBean(), method.getMethod(), parameterArray);
if (!CollectionUtils.isEmpty(errInfoSet)) {
throw new BusiException(errInfoSet.iterator().next().getMessage());
}
return true;
}
/**
* Intercept the execution of a handler. Called after HandlerAdapter actually
* invoked the handler, but before the DispatcherServlet renders the view.
* Can expose additional model objects to the view via the given ModelAndView.
* <p>DispatcherServlet processes a handler in an execution chain, consisting
* of any number of interceptors, with the handler itself at the end.
* With this method, each interceptor can post-process an execution,
* getting applied in inverse order of the execution chain.
*
* @param request current HTTP request
* @param response current HTTP response
* @param handler chosen handler to execute, for type and/or instance examination
* @param modelAndView the <code>ModelAndView</code> that the handler returned
* (can also be <code>null</code>)
* @throws Exception in case of errors
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
}
Spring提供的校驗工廠支持各種校驗器的驗證,本文中是對Hibernate的實體的屬性的各種註解進行校驗,例如在控制層的方法入參配置了非空校驗,則這裏將會進行攔截判空。