1. 程式人生 > >SpringMVC(8) - 處理器對映

SpringMVC(8) - 處理器對映

  在以前的Spring版本中,使用者需要在Web應用程式上下文中定義一個或多個HandlerMapping bean,以將傳入的Web請求對映到適當的處理器。通過引入帶註解的控制器,就不需要像之前那樣定義了,因為RequestMappingHandlerMapping會自動在所有@Controller bean上查詢@RequestMapping註解。但是,請記住,從AbstractHandlerMapping擴充套件的所有HandlerMapping類都具有以下可用於自定義其行為的屬性:
  
  攔截器:使用的攔截器列表
  
  defaultHandler:當此處理器對映未找到匹配的處理器時使用的預設處理器。
  
  order:基於order屬性的值(參考org.springframework.core.Ordered介面),Spring對上下文中可用的所有處理程式對映進行排序,並應用第一個匹配的處理器。
  
  alwaysUseFullPath:如果為true,則Spring使用當前Servlet上下文中的完整路徑來查詢適當的處理器序。如果為false(預設值),則使用當前Servlet對映中的路徑。例如,如果使用 /testing/* 對映Servlet並且將alwaysUseFullPath屬性設定為true,則使用 /testing/viewPage.html,而如果該屬性設定為false,則使用/viewPage.html。
  
  urlDecode:從Spring 2.5開始,預設為true。如果希望比較編碼路徑,將此標誌設定為false。但是,HttpServletRequest始終以解碼形式暴露Servlet路徑。請注意,Servlet路徑與編碼路徑相比是不匹配的。
  
  以下示例顯示如何配置攔截器:
  
  <beans>
  
  <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
  
  <property name="interceptors">
  
  <bean class="example.MyInterceptor"/>
  
  </property>
  
  </bean>
  
  <beans>
  
  1. 使用HandlerInterceptor攔截請求
  
  Spring的處理器對映機制包括處理器攔截器,當想要將特定功能應用於某些請求(例如,檢查認證資訊)時,它們很有用。
  
  位於處理器對映中的攔截器必須從org.springframework.web.servlet.HandlerInterceptor。該介面定義了三種方法,這三種方法應該提供足夠的靈活性來進行各種預處理和後處理,方法如下:
  
  在執行實際處理程式之前呼叫preHandle(..)
  
  執行處理程式後呼叫postHandle(..)
  
  完成請求完成後呼叫afterCompletion(..)
  
  preHandle(..)方法返回一個布林值。可以使用此方法來中斷或繼續執行鏈的處理。當此方法返回true時,處理程式執行鏈將繼續;當它返回false時,DispatcherServlet假定攔截器本身已處理請求(例如,呈現了適當的檢視),並且不繼續執行執行鏈中的其他攔截器和實際處理器。
  
  可以使用interceptors屬性配置攔截器,該屬性存在於從AbstractHandlerMapping擴充套件的所有HandlerMapping類中。示例:
  
  <beans>
  
  <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
  
  <property name="interceptors"www.hjshidpt.com>
  
  <list>
  
  <ref bean=www.yigouyule2.cn"officeHoursInterceptor"/>
  
  </list>
  
  </property>
  
  </bean>
  
  <bean id="officeHoursInterceptor" class="www".michenggw.com"samples.TimeBasedAccessInterceptor">
  
  <property name="openingTime"www.gcyl152.com value="www.gcyl159.com 9"/>
  
  <property name="closingTime" value="18"/>
  
  </bean>
  
  </beans>
  
  TimeBasedAccessInterceptor攔截此對映處理的任何請求。如果當前時間不在辦公時間,則會將使用者重定向到靜態HTML檔案,例如,只能在辦公時間訪問該網站。
  
  package samples;
  
  public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
  
  private int openingTime;
  
  private int closingTime;
  
  public void setOpeningTime(int openingTime) {
  
  this.openingTime = openingTime;
  
  }
  
  public void setClosingTime(int www.mcyllpt.com closingTime) {
  
  this.closingTime = closingTime;
  
  }
  
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
  
  Object handler)www.furggw.com throws Exception {
  
  Calendar cal = Calendar.getInstance();
  
  int hour = cal.get(HOUR_OF_DAY);
  
  if (openingTime <= hour && hour < closingTime) {
  
  return true;
  
  }
  
  response.sendRedirect("http://host.com/outsideOfficeHours.html");
  
  return false;
  
  }
  
  }
  
  注:使用RequestMappingHandlerMapping時,實際的處理器是HandlerMethod的一個例項,它標識將被呼叫的特定控制器方法。
  
  如上例,Spring介面卡類HandlerInterceptorAdapter使擴充套件HandlerInterceptor介面變得更容易。
  
  提示:在上面的示例中,配置的攔截器將應用於使用帶註解的控制器方法處理的所有請求。如果要縮小攔截器應用的URL路徑,可以使用MVC名稱空間或MVC Java配置,或者宣告型別為MappedInterceptor的bean例項來執行此操作。
  
  請注意,HandlerInterceptor的postHandle方法並不總是非常適合與@ResponseBody和ResponseEntity方法一起使用。在這種情況下,HttpMessageConverter在呼叫postHandle之前寫入並提交響應,這使得無法更改響應,例如新增響應頭。相反,應用程式可以實現ResponseBodyAdvice並將其宣告為@ControllerAdvice bean或直接在RequestMappingHandlerAdapter上配置它。