Spring Interceptor會按照提示進行操作:在傳入的HTTP請求到達您的Spring MVC控制器類之前對其進行攔截,或者相反,在其離開您的控制器之后但在將其反饋給瀏覽器之前,對其進行攔截。
您可能會問這對您有什么用? 答案是,它允許您執行每個請求或一組請求共有的任務,而無需將“ n”粘貼樣板代碼切成每個控制器類。 例如,您可以在請求到達控制器之前執行用戶身份驗證,如果成功,則從數據庫中檢索一些其他用戶詳細信息,然后在調用控制器之前將其添加到HttpServletRequest對象。 然后,您的控制器可以簡單地檢索和使用這些值,或將其留給JSP顯示。 另一方面,如果身份驗證失敗,則可以將用戶重定向到其他頁面。
演示代碼向您展示如何在傳入的HttpServletRequest對象到達控制器之前對其進行修改。 這無非是向請求中添加一個簡單的字符串,但是,正如我上面所說,您始終可以進行數據庫調用來獲取每個請求所需的一些數據……您甚至可以添加某種優化并進行一些處理此時進行緩存。
public class RequestInitializeInterceptor extends HandlerInterceptorAdapter {// Obtain a suitable logger.private static Log logger = LogFactory.getLog(RequestInitializeInterceptor.class);/*** In this case intercept the request BEFORE it reaches the controller*/@Overridepublic boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {try {logger.info("Intercepting: " + request.getRequestURI());// Do some changes to the incoming request objectupdateRequest(request);return true;} catch (SystemException e) {logger.info("request update failed");return false;}}/*** The data added to the request would most likely come from a database*/private void updateRequest(HttpServletRequest request) {logger.info("Updating request object");request.setAttribute("commonData","This string is required in every request");}/** This could be any exception */private class SystemException extends RuntimeException {private static final long serialVersionUID = 1L;// Blank}
}
在上面的代碼中,我通過擴展HandlerInterceptorAdaptor類(覆蓋preHandle(..)方法)選擇了最簡單的實現方法。 我的preHandle(...)方法進行錯誤處理,確定發生錯誤時的處理方法,如果發生錯誤則返回false。 返回false時,攔截器鏈會斷開,并且不會調用您的控制器類。 與請求對象混淆的實際事務被委托給updateRequest(request)。
HandlerInterceptorAdaptor類具有三個方法,每個方法都被存根,如果需要,可以忽略。 這些方法是:prehandle(…),postHandle(…)和afterCompletion(…),有關這些的更多信息可以在Spring API文檔中找到 。 請注意,這可能會造成一些混亂,因為Handler Interceptor類文檔仍通過它們的Spring 2處理程序名稱來引用MVC控制器類。 如果您查看prehandle(…)的Object類型的第三個參數(稱為處理程序),則很容易證明這一點。 如果在調試器中進行檢查,您將看到它是控制器類的實例。 如果您不熟悉這項技術,請記住該控制器==處理程序。
與往常一樣,實現攔截器的下一步是向Spring XML配置文件中添加一些內容:
<!-- Configures Handler Interceptors -->
<mvc:interceptors> <!-- This bit of XML will intercept all URLs - which is what you want in a web app --><bean class="marin.interceptor.RequestInitializeInterceptor" /><!-- This bit of XML will apply certain URLs to certain interceptors --><!-- <mvc:interceptor><mvc:mapping path="/gb/shop/**"/><bean class="marin.interceptor.RequestInitializeInterceptor" /></mvc:interceptor>-->
</mvc:interceptors>
上面的XML演示了向所有請求URL添加攔截器的一種或一種選擇,或者如果您查看注釋掉的部分,則向特定的請求URL添加攔截器,從而允許您選擇將哪些URL連接到您的攔截器類。
鷹眼的讀者可能已經注意到,攔截器類使用繼承和XML配置作為其實現方法。 在配置方面的常規情況下,這種模式看起來有些疲憊,并且可能需要進行大修。 一種建議是使用已添加到控制器機制中的相同技術來增強整體以使用注釋。 這將增加額外的靈活性,而不會導致使用所有接口和抽象基類的復雜性。 作為建議,將來的攔截器類實現可能如下所示:
@Intercept(value = "/gb/en/*", method = RequestMethod.POST)public boolean myAuthenticationHandler(HttpServletRequest request,Model model) {// Put some code here}
這樣就結束了對Spring攔截器的了解,應該記住,我只是展示了最基本的實現。
參考:來自Captain Debug博客的 JCG合作伙伴 Roger Hughes在MVC Webapp中使用Spring Interceptor 。
- jqGrid,REST,AJAX和Spring MVC集成
- SpringMVC 3 Tiles 2.2.2集成教程
- Spring MVC3 Hibernate CRUD示例應用程序
- Spring MVC開發–快速教程
- Spring,Quartz和JavaMail集成教程
- Spring Insight – Web應用程序分析
- Java教程和Android教程列表
翻譯自: https://www.javacodegeeks.com/2011/10/spring-mvc-interceptors-example.html