SpringMVC框架學習

1 SpringMVC框架

         整個框架主要是圍繞一個DispatcherServlet來進行設計的web

         該Servlet會將請求分發給各個處理器,並支持可配置的處理器映射、視圖渲染、本地化、時區與主題渲染等spring

         其中,處理器是應用中註解了 @Controller 和 @RequestMapping的類和方法編程

 

DispatcherServletapp

         DispatcherServlet其實就是一個Servlet(繼承自HttpServlet基類)。同時,須要在web.xml文件中把須要處理的請求映射到URL上去,通常狀況下,web.xml須要配置 DispatcherServlet 和路徑映射的聲明框架

         例如:佈局

                   <web-app>this

                            <servlet>url

                                     <servlet-name>example</servlet-name>spa

                                     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>設計

                                     <load-on-startup>1</load-on-startup>

                            </servlet>

                            <servlet-mapping>

                                     <servlet-name>example</servlet-name>

                                     <url-pattern>/example/*</url-pattern>

                            </servlet-mapping>

                   </web-app>

                   以上代碼,全部路徑以 /example 開頭的請求都被會名字爲 example 的 DispatcherServlet處理。

         在Servlet3.0的環境下,還能使用編程的方式配置Servlet容器(暫不表)

 

         DispatcherServlet的初始化過程,SpringMVC會在web應用的WEB-INF目錄下查找一個名爲 [servlet-name]-servlet.xml的配置文件,並建立其中所定義的bean

         若是全局上下文中存在相同名字的bean,則它們會被新定義的同名bean覆蓋

                   <web-app>

                            <servlet>

                                     <servlet-name>golfing</servlet-name>

                                     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

                                     <load-on-startup>1</load-on-startup>

                            </servlet>

                            <servlet-mapping>

                                     <servlet-name>golfing</servlet-name>

                                     <url-pattern>/golfing/*</url-pattern>

                            </servlet-mapping>

                   </web-app>

                   有了以上的 Servlet的配置文件,還須要在應用的/WEB/INF路徑下建立一個 golfing-servlet.xml文件,該文件定義了全部SpringMVC相關的組件(例如bean)

 

         Spring當中的 ApplicationContext 實例都是有範圍(scope)的。在SrpingMVC當中,每個 DispatcherServlet 都有一個本身的 WebApplicationContext 上下文對象,它繼承了root的 WebApplicationContext對象中的全部bean,若是這個集成的bean在具體的 Servlet實例中被重載,在每一個Servlet實例中能夠定義其scope下的新的bean。

         若是應用當中只須要一個 DispatcherServlet 時,此時只須要配置一個根 context對象就好了。要配置一個惟一的context對象,直接在初始化參數中 配置一個空的 contextConfigLocation便可 

         web.xml

                   <web-app>

                       <context-param>

                           <param-name>contextConfigLocation</param-name>

                           <param-value>/WEB-INF/root-context.xml</param-value>

                       </context-param>

                       <servlet>

                           <servlet-name>dispatcher</servlet-name>

                           <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

                           <init-param>

                               <param-name>contextConfigLocation</param-name>

                               <param-value></param-value>

                           </init-param>

                           <load-on-startup>1</load-on-startup>

                       </servlet>

                       <servlet-mapping>

                           <servlet-name>dispatcher</servlet-name>

                           <url-pattern>/*</url-pattern>

                       </servlet-mapping>

                       <listener>

                           <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

                       </listener>

                   </web-app>

 

                   WebApplicationContext 繼承自 ApplicationContext ,它提供了一些web應用常常須要用到的特性

 

定製 DispatcherServlet 的配置,具體作法是,在 web.xml 文件中,Servlet 的聲明元素上添加一些 Servlet 的初始化參數(經過 init-param 元素)。可選參數列表以下:

         contextClass

                  任意實現了 ApplicationContext 的類,這個類會初始化 Servlet 所須要的上下文對象。默認狀況下,框架會使用 XmlWebApplicationContext對象

         contextConfigLocation

                   用於指定上下文配置文件路徑的字符串,這個值會被傳入給 contextClass 指定的上下文對象。該字符串內能夠包含多個字符串,字符串之間以逗號分割,以此支持多個上下文的配置。在多個上下文中重複定義的bean,以最後加在的bean定義爲準

         namespace

                   WebApplicationContext 的命名空間。默認是 [servlet-name]-servlet

 

2 WebApplicationContext (應用上下文)中特殊的bean類型

         bean的類型

                   HandlerMapping

                            處理器映射。根據規則將進入容器的請求映射到具體的處理器。最多見的一個實現是支持你在控制器上添加註解,配置請求路徑。固然,也存在其餘實現

                   HandlerAdapter

                            處理器適配器。黨拿到所對應的處理器後,適配器將負責去調用該處理器,這使得DispathcerServlet無需關心具體的調用細節。例如,要調用的是一個機遇註解配置的控制器,那麼調用前還須要從註解中解析相關配置信息。所以,HandlerAdapter具體的工做就是對 DispatcherServlet 屏蔽這些細節

                   HandlerExceptionResolver

                            處理器異常映射。主要負責將捕獲的異常映射到不一樣的視圖上去

                   ViewResolver

                            視圖解析器。負責將邏輯視圖名(String)映射到一個具體實際的view上去

                   LocaleResolver & LocaleContextResolver

                            地區解析器 和 地區上下文解析器。它們負責解析客戶端所在的地區信息甚至時區信息,爲國際化的視圖定製提供支持。

                   ThemeResolver

                            主題解析器。負責解析web當中可用的主題,好比一些個性化定製的佈局

                   MulipartResolver

                            解析multi-part的傳輸請求,好比支持經過HTML表單進行的文件上傳等。

                   FlashMapManager

 

 

3 DispatcherServlet 的處理流程

         請求通過DispatcherServlet時,DispatcherServlet會按照以下次序對請求進行處理:

                   a 首先,搜索本 DispatcherServlet 對應的應用上下文對象 WebApplicationContext,並將它做爲一個屬性綁定到該請求,以方便之後的控制器和其餘組件可以使用它,屬性的鍵名默認爲

                   DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE

                   b 將時區(locale)解析器綁定到請求上,以便其餘組件在處理請求(渲染視圖、準備數據等)時能夠獲取到時區的相關信息,若不須要,可忽略此項

                   c 將主題(theme)解析器綁定到請求上,同理

                   d 若是你配置了multipart文件處理器,那麼框架將查找該文件是否是multipart(分爲多個部分連續上傳)的。如果,則將該請求包裝成一個 MultipartHttpServletRequest 對象,以便處理鏈中的其餘組件對它作進一步的處理。

                   e 爲請求尋找一個合適的處理器,若是處理器被找到,則整個執行蓮(前處理器,後處理器,控制器等)都會被執行,以完成相應模型的準備或視圖的渲染

                   f 若是返回獲得了一個模型model,那麼此時直接將該model渲染成相應的視圖view,若沒有任何返回模型。則不會渲染,並默認請求的處理已經由請求鏈處理完畢。

         若是在處理的過程當中跑出了異常,,那麼上下文 WebApplicationContext 對象中所定義的異常處理器將會負責捕獲這些異常。經過配置你本身的異常處理器,你能夠定製本身處理異常的方式。

 

4 控制器的實現

         控制器是應用程序邏輯的處理入口,Spring對控制器的定義相對寬鬆,實現控制器很自由

         例如能夠在控制器上添加

         @RequestMapping   @RequestParam   @ModelAttribute

 

         @Controller

         public class HelloWorldController {

             @RequestMapping("/helloWorld")

             public String helloWorld(Model model) {

                 model.addAttribute("message", "Hello World!");

                 return "helloWorld";

             }

         }

 

5 @Controller關鍵字

         使用@Controller關鍵字,代表了該類是一個做爲控制器而存在的角色,Spring此時不要求你去集成任何控制器基類,也不須要去實現Servlet的那套API,固然若是須要也能夠去實現

 

         @Controller註解被認爲是這個類的原型,代表這個類所承擔的角色。分派器(DispatcherServlet)會掃描全部註解了@Controller的類,檢測其中經過@RequestMapping註解配置的方法

 

         <?xml version="1.0" encoding="UTF-8"?>

         <beans xmlns="http://www.springframework.org/schema/beans"

                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                xmlns:p="http://www.springframework.org/schema/p"

                xmlns:context="http://www.springframework.org/schema/context"

                xsi:schemaLocation="

         http://www.springframework.org/schema/beans

         http://www.springframework.org/schema/beans/spring-beans.xsd

         http://www.springframework.org/schema/context

         http://www.springframework.org/schema/context/spring-context.xsd">

             <context:component-scan base-package="org.springframework.samples.petclinic.web"/>

             <!-- ... -->

         </beans>

 

      5.1 @RequestMapping關鍵字

         該關鍵字主要用來將請求 URL 映射到整個類上或者某個特定的方法上

         一般,一個類的註解將某個連接映射到一個具體的控制器上,而其中的方法的映射則是更加細化了處理,便可以根據特定的HTTP請求方法(GET/POST等)、查看HTTP請求中是否攜帶特定參數等條件,將請求映射到匹配的方法上

 

         @Controller

         @RequestMapping("/appointments")

         public class AppointmentsController {

             private final AppointmentBook appointmentBook;

             @Autowired

             public AppointmentsController(AppointmentBook appointmentBook) {

                 this.appointmentBook = appointmentBook;

             } @

                     RequestMapping(method = RequestMethod.GET)

             public Map<String, Appointment> get() {

                 return appointmentBook.getAppointmentsForToday();

             } @

                     RequestMapping(path = "/{day}", method = RequestMethod.GET)

             public Map<String, Appointment> getForDay(@PathVariable @DateTimeFormat(iso=ISO.DA

                     TE) Date day, Model model) {

                 return appointmentBook.getAppointmentsForDay(day);

             } @

                     RequestMapping(path = "/new", method = RequestMethod.GET)

             public AppointmentForm getNewForm() {

                 return new AppointmentForm();

             } @

                     RequestMapping(method = RequestMethod.POST)

             public String add(@Valid AppointmentForm appointment, BindingResult result) {

                 if (result.hasErrors()) {

                     return "appointments/new";

                 } a

                 ppointmentBook.addAppointment(appointment);

                 return "redirect:/appointments";

             }

         }

         類級別的@RequestMapping不是必須的,若不配置的前提下,則其中方法的映射都是絕對路徑,而不是相對路徑

相關文章
相關標籤/搜索