- Handler mappings
- Spring 2.5 以後 DispatcherServlet 預設使用 DefaultAnnotaionHandlerMapping 去找 @Controller 裡的 @RequestMapping,所以不用在 xml 裡定義 handler mapping 了。
- DefaultAnnotaionHandlerMapping 有些屬性可以設定:
- interceptors
- defaultHandler - 找不到符合的 handler 時,設定預設的 handler。
- order - 設定多筆 handler mapping 時使用。
- alwaysUseFullPath - 假設 servlet 過濾的 url pattern 為 /abc/*,一個 request 的 url 為 /abc/def.do,若設為 true,則用 /abc/def.do 去找 handler,若設為 false,則用 /def.do 去找,預設為 false。
- urlDecode - 預設為 true。
- lazyInitHandlers - 用來將 singleton handler lazy init,預設為 false。
<bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> <property name="interceptors"> <bean class="example.MyInterceptor"/> </property> </bean>
- HandlerInterceptor
- 可以實作 HandlerInterceptor 或繼承 HandlerInterceptorAdapter。
- preHandle - handler 執行前呼叫,可回傳 false,表示已自行處理 request,不用再執行 handler。
- postHandle - handler 執行完成後呼叫。
- afterCompletion - 整個 request 處理完畢時呼叫。
- Resolving views
- Spring 在 view 的處理上有兩個 interface:
- ViewResolver - 將 view name 對應到 view 物件上。
- View - view 物件。
- handler method 必須回傳 view name:
- 精確的方式,可以回傳 view name、ModelAndView、View。
- 模糊的方式,使用程式慣例。
- Spring 支援的 view resolver:
- AbstractCachingViewResolver - 支援 view cache,可以設定 cache 為 false 來關閉 cache 功能。
- XmlViewResolver - 使用 Spring XML bean 風格的設定檔。
- ResourceBundleViewResolver - 使用 properties 風格的設定檔。
- UrlBasedViewResolver - 模糊的方式,將 url 視為 view name。
- InternalResourceViewResolver - 繼承 UrlBasedViewResolver,支援像 JstlView 或 TilesView 之類的 InternalResourceVie,可以自訂 view class。
- VelocityViewResolver / FreeMarkerViewResolver - 繼承 UrlBasedViewResolver,支援 Velocity / FreeMarker。
- ContentNegotiatingViewResolver
- 使用 JSP view
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean>
- 使用多種 view
- 以 [view name].(class) 設定 view class。
- 以 [view name].url 設定 view url。
- 可以設定 defaultParentView,其他 view 都會繼承這個 defaultParentView。
<bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver"> <property name="basename" value="views"/> <property name="defaultParentView" value="parentView"/> </bean>
- Spring 支援同時使用多種 view resolver,可以用 order 屬性決定執行順序,數值愈大優先權愈低。
- Spring 從 order 數值小的開始找,如果沒找到才會往下一個 view resolver 去找。
- 有些 view resolver 找不到合適的 view 時會回傳 null,這種的 view resolver 適合放在隊伍前面,而像 InternalResourceViewResolver 這種無法決定是否有符合的 view 存在的就一定要排在後面。
- Redirect
- 使用 RedirectView class。
- 使用 redirect: 字首,用在 UrlBasedViewResolver 與其子類別。
- Forward
- UrlBasedViewResolver 與其子類別支援 forward: 字首。
- Locale
- Theme
- File upload
- Spring 預設不處理 file upload,必須加上以下的設定,並加入commons-fileupload.jar。
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- maximum file size in bytes --> <property name="maxUploadSize" value="100000"/> </bean>
- form 要加上 enctype="multipart/form-data"。
<form method="post" action="/form" enctype="multipart/form-data"> <input type="text" name="name"/> <input type="file" name="file"/> <input type="submit"/> </form>
- handler 的 request 要用 MultipartHttpServletRequest,用 MultipartFile 取檔案。
@RequestMapping(value = "/form", method = RequestMethod.POST) public String handleFormUpload(@RequestParam("name") String name, @RequestParam("file") MultipartFile file) { if (!file.isEmpty()) { byte[] bytes = file.getBytes(); // ... return "redirect:uploadSuccess"; } else { return "redirect:uploadFailure"; } }
- Exception
- 可以實做 HandlerExceptionResolver。
- 或者直接使用 SimpleMappingExceptionResolver 設定 exception 與 view name 的對應,
- 或者使用 @ExceptionHandler,僅是用於該 @Controller 裡的 @RequestMapping,傳入的 method param 與回傳值與 @RequestMapping 一樣有彈性,@ExceptionHandler 也可以傳入 exception array,或者不輸入,以 method param 定義為依據。
@ExceptionHandler(IOException.class) public String handleIOException(IOException ex, HttpServletRequest request) { return ClassUtils.getShortName(ex.getClass()); }
- Convention over configuration
- 主要用在 model、view、controller 三部份。
- 有了 annotation 之後,coc 幾乎沒用了,只剩下 view 有用。
- Spring 提供 ReqeustToViewNameTranslator 與其實作 DefaultRequestToViewNameTranslator,當 handler method 沒有提供 view name 時,就會以 url 為 view name。
- mvc namespace
- mvc:annotation-driven
- 為了使用 @Controller,必須註冊 DefaultAnnotationHandlerMapping 與 AnnotationHandlerMethodAdapter 這兩個 bean,mvc:annotation-driven 就是用合理的預設值來註冊這兩個 bean。
- mvc:interceptors
- 設定 HandlerInterceptor 或 WebReqeustInterceptor。
- 可以套用到所有的 request,或者指定 url pattern。
<mvc:interceptors> <bean class="org.example.SecurityInterceptor" /> <mvc:interceptor> <mapping path="/secure/*"/> <bean class="org.example.SecurityInterceptor" /> </mvc:interceptor> </mvc:interceptors>
- mvc:view-controller
- 用來註冊 ParameterizableViewController。
- 不用經過 handler,直接跳到 view 去。
<mvc:view-controller path="/" view-name="home"/>
- mvc:resources
- 用於靜態檔案 mapping 與 cache。
- mapping 屬性使用 Ant pattern。
- location 屬性可以設定一或多個目錄位置,用逗號區隔多筆,順序有關係,可以用 classpath: 字首。
- 可以加上 cache-period 來設定暫存時間,以秒為單位,建議搭配 version 字串來強制更新版本。
<mvc:resources mapping="/resources/**" location="/public-resources/"/>
- mvc:default-servlet-handler
- ...
沒有留言:
張貼留言