springMVC-interceptors

Handler mappings

In previous versions of Spring,users were required to define one or more HandlerMapping 
beans in the web application context to map incoming web requests to appropriate 
handlers.With the introduction of annotated controllers, you generally don't need to do
 that because the RequestMappingHandlerMapping automatically looks fo @RequestMapping 
annotations on all @Controller beans.However, do keep in mind that all HandlerMapping 
classes extending from AbstractHandlerMapping have the following properties that you can 
use to customize their behavior;

在spring的早期版本,需要配置很多HandlerMapping,但是後來引入了@RequestMapping註解,就不需要配置了。但是仍然需要記住,HandlerMapping類都繼承AbstractHandlerMapping,他們具有以下屬性。

  • interceptors List of interceptos to use. HandlerInterceptors are discussed in the section called
    “Intercepting requests with a HandlerInterceptor”

可以使用攔截器列表

  • defaultHandler Default handler to use, when this handler mapping does not result in a matching
    handler

當HandlerMapping不指向任何攔截器的時候,將指向默認的攔截器

  • order Based on the value of the order property(see the org.springfrwmework.core.Ordered
    interface),Spring sorts all handler mappings available in the context and applies the first matching
    handler.

spring排序了所有的的applies,並且只匹配第一個handler

  • alwaysUseFullPath if true, Spring uses the full path within the current Servlet context to find an appropriate handler.If false(the default), the path within the current Servlet mapping is used.For
    example, if a Servlet is mapped using /testing/* and the alwaysUseFullPath property is set to true,
    /testing/viewPage.html is used,whereas if the property is set to false,/viewPage.html is used.

使用全路徑名,如果設置爲ture,Spring在上下文中使用全路徑名。如果設置爲false(默認情況下是false),路徑會結合着當前Servlet的路徑使用。例如,Servlet映射是/testing/*alwaysUserFullPath屬性設置爲了true,/testing/viewPage.html 會被使用,如果設置爲false,/viewPage.html會被使用。

  • urlDecode Defaults to true, as of Spring 2.5.If you prefer to compare encoded paths, set this flag
    to false.However,the HttpServletRequest always exposes the Servlet path in decoded form.
    Be aware that the Servlet path will not match when compared with encoded paths.

url編碼,2.5以上的spring默認情況爲true。如果你願意比較編碼路徑,設置爲false。可是HttpServletRequest通常會以解碼後形式暴露Servlet路徑。並且要注意,Servlet路徑回合加密後的路徑不匹配。

下面是configure一個攔截器。

<beans>
    <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
    <property name="interceptors">
        <bean class="example.MyInterceptor"/>
    </property>
</beans>

Intercepting requests with a HandlerInterceptor

Spring's handler mapping mechanism includes handler interceptors,which are useful when 
you want to apply specific functionflity to certain requests,for example, checking for a 
principal.

spring處理器驗證機制中會包含有攔截器,當你想要給某一個請求增加一個特殊的功能例如驗證某一個規則,這個時候攔截器就會顯的很有用。

Interceptors  located in the handler mapping must implement HandlerInterceptor from the 
org.springframework.web.servlet package.This interface defines three 
methods:preHandle(..)is called  before the actual handler is executed; postHandle(..)is 
called after the handler is executed ; and afterCompletion(..) is called after the 
complete request  has finished. These three methods should provide enough flexibility to 
do all kinds of preprocessing and postprocessing.

位於handler mapping中的攔截器必須實現HandlerInterceptor接口。這個接口定義了三個方法:preHandle(..):在相應的處理器被執行前進行調用;postHandle(..)在handler被執行之後調用;afterCompletion(..)在請求完成之後調用。這三種方法對於預處理和完成處理提供了足夠的靈活性。

The preHandle(..) method returns a boolean value. You can see this method to break or 
continue the processing of the execution chain. When this method returns ture, the 
handler exection chain will continue; when i returns false, the DispatcherServlet 
assumes the interceptor itself has taken care of requests (and ,for example,rendered an 
appropriate view) and does not continue executing the other interceptors and the actual 
handler in the execution chain.

preHandle會返回一個boolean值。preHandle可以中斷或者繼續執行處理鏈。當返回true的時候會繼續執行處理鏈,當返回false的時候會中斷處理鏈。當返回false的時候,DispatcherServlet 會假設攔截器可以處理相應的請求(比如返回一個視圖,或者返回某些信息),因此DispatcherServlet不會讓其他攔截器或者真正的處理器進行處理。

Interceptors can be configured using the interceptors property, which is present on all 
HandlerMapping classes extending from AbstractHanlerMapping .This is shown in the 
example
<beans>
    <bean id="handleMapping"
        class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandleMapping">
        <property name="interceptors">
            <list>
                <ref bean="officeHoursInterceptor"/>
            </list>
        </property>
    </bean>
    <bean id="officeHoursInterceptor" class="samples.TimeBasedAccessInterceptor">
        <property name="openingTime" value="9"/>
        <property name="closeingTime" value="18"/>
    </bean>
</beans>
public class TimeBaseAccessInterceptor extends HandlerInterceptorAdapter{
    private int openingTime;
    private int closeingTime;

    public void setOpeningTime(int openingTime){
        this.openingTime = openingTime;
    }

    public void setClosingTime(int closingTime){
        this.closingTime = closingTime;
    }

    public boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object Handler){
        Calendar cal = Calendar.getInstance();
        int hour = cal.get(HOUR_OF_DAY);
        if(openTime <= hour && hour < closingTime){
            return true;
        }
        response.sendRedirect("sfasdfasdfa");
        return false;
    }
}
Any request handled by this mapping is intercepted by the TimeBasedAccessInterceptor. If 
the current time is outside office hours, the user is redirected to static HTML file 
that will be invoked.

任何被這種映射處理的請求都會被TimeBasedAccessInterceprot攔截。如果當前時間超過了辦公時間,用戶將會被重定向到一個靜態的html。

when using the RequestMappingHandlerMapping the actual handler is an instance of 
HandlerMethod which identifies the specific controller method that will be invoked.

當使用RequestMappingHandlerMapping的時候真正的處理器其實是其實是HandlerMethod的一個實例,HandlerMethod實例會調用某個特定處理器的方法。

As you can see, the Spring   adapter class HandlerInterceptorAdapter makes it easier to 
extend   the HandlerInterceptor interface.

如果覺的實現HandlerInterceptor比較困難,可以選擇繼承HandlerInterceptorAdapter。

Tip

In the example above, the configured interceptor will apply to all requests handled with 
annotated controller methods. If you want to narrow down the URL paths to which an 
interceptor applies,you can use the MVC namespace or the MVC java config, or declare
 bean instances of type MappedInterceptor to do that .

Note that the postHandle method of HandlerInterceptor is not always ideally suited for use with @ResponseBody and ResponseEntity methods. In such cases an HttpMessageConverter writes to and commits the response before postHandle is called which makes it impossible to change the response, for example to add a header. Instead an application can implement ResponseBodyAdvice and either declare it as an @ControllerAdvice bean or configure it directly on RequestMappingHandlerAdapter.
You can configure HandlerInterceptors or WebRequestInterceptors bo be applied to all
 incoming requests or restricted to specific URL path patterns.

In XML use the element:

<mvc:interceptors>
    <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
    <mvc:interceptor>
        <mvc:mappint path="/**"/>
        <mvc:exclude-mapping path="/admin/**"/>
        <bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"/>
    </mvc:interceptor>
    <mvc:interceptor>
        <mvc:mapping path="/secure/*"/>
        <bean class="org.example.SecurityInterceptor"/>
    </mvc:interceptor>
</mvn:interceptors>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章