Spring的MVC web框架學(xué)習(xí)筆記
1、Spring web 框架的核心:DispatcherServlet
DispatcherServlet 用于接收請(qǐng)求。是使用Spring框架的入口。在web.xml中,需要配置該servlet。在配置該Servlet的時(shí)候url-pattern你可以使用你自己想使用的形式,如*.aspx,*.do,*.htm,*.action,用以混淆客戶端對(duì)服務(wù)器架構(gòu)的認(rèn)識(shí)。
另外,該Servlet在容器中還會(huì)加載一個(gè)APPlicationContext的xml文件。默認(rèn)加載的是[servlet-name]-servlet.xml。例如,你在web.xml中配置的servlet如下:
<web-app> <servlet> <servlet-name>example</servlet-name> <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>*.form</url-pattern> </servlet-mapping> </web-app>
該Servlet就會(huì)在服務(wù)器啟動(dòng)時(shí),加載example-servlet.xml。當(dāng)然,你也可以自己來(lái)指定加載文件。
要看看DispatcherServlet真面目,打開源文件,發(fā)現(xiàn)定義了很多BeanName的常量,如本地化解析器beanname,主題解析器beanname,視圖解析器beanname,上傳文件解析的multipart解析器beanname。
等:
public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver"; public static final String LOCALE_RESOLVER_BEAN_NAME = "localeResolver"; public static final String THEME_RESOLVER_BEAN_NAME = "themeResolver"; public static final String HANDLER_MAPPING_BEAN_NAME = "handlerMapping"; public static final String HANDLER_ADAPTER_BEAN_NAME = "handlerAdapter"; public static final String HANDLER_EXCEPTION_RESOLVER_BEAN_NAME = "handlerExceptionResolver"; public static final String REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME = "viewNameTranslator"; public static final String VIEW_RESOLVER_BEAN_NAME = "viewResolver";
這個(gè)類怎么使用這些bean呢?以上面的exexample-servlet.xml為例,我們定義的名字為example的DispatcherServlet使用example-servlet.xml的配置。在example-servlet.xml里,我們可以配置名字上面的beanName的bean,來(lái)讓servlet加載這些bean。
這下明白了,servlet.xml該怎么配置,該配置什么了。
好了,看完了最重要的servlet的配置問(wèn)題,我們?cè)倏聪乱粋€(gè)重要的接口:Controller。至于上面servlet要使用的什么什么解析器啦,我們稍后在分析。
2、Controller
我們的請(qǐng)求提交到DispacherServlet后,會(huì)轉(zhuǎn)給Controller。怎么找Controller?通過(guò)使用handlerMapping。如果沒有設(shè)置handlerMapping,spring使用默認(rèn)的BeanNameUrlHandlerMapping來(lái)找Controller。
BeanNameUrlHandlerMapping?顧名思義,就是通過(guò)bean的name屬性來(lái)映射controller。bean的name請(qǐng)求是一個(gè)url,如果請(qǐng)求的是logout.do,在example-servlet.xml中定義一個(gè)名字(name)為login.do的Controller.
<bean name="/logout.do" class="com.jy.bookshop.web.spring.LogoutController">
</bean>
再插一句話,在handlerMapping中,我們可以使用請(qǐng)求攔截器來(lái)對(duì)請(qǐng)求進(jìn)行攔截處理。該攔截器怎么使用這里暫且不表,有機(jī)會(huì)再討論。
ok,現(xiàn)在我們創(chuàng)建一個(gè)LogoutController來(lái)讓他處理請(qǐng)求,讓他實(shí)現(xiàn)Controller吧:
public class LogOutController implements Controller { public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse res) throws Exception { … return new ModelAndView(new RedirectView("login.do")); } }
看看這個(gè)Controller接口的定義,發(fā)現(xiàn)這個(gè)接口只定義了一個(gè)handleRequest方法。在這個(gè)方法中,返回一個(gè)ModelAndView。
先說(shuō)ModelAndView。我們知道MVC,那么ModelAndView就是 MV了。Controller就是C。這樣MVC全了。呵呵。
繼續(xù)說(shuō)ModelAndView,要了解他的結(jié)構(gòu),那自然要看看他的源代碼了:
/** View instance or view name String */ private Object view; /** Model Map */ private ModelMap model;
只關(guān)注我們關(guān)注的,里面包含了一個(gè)View對(duì)象和model對(duì)象。model對(duì)象是一個(gè)Map,這里不再說(shuō)了。關(guān)鍵看看view,奇怪,怎么是一個(gè)Object,太抽象了。再繼續(xù)看源代碼的話,會(huì)更加明白:
public ModelAndView(String viewName, String modelName, Object modelObject) { this.view = viewName; addObject(modelName, modelObject); } public void setViewName(String viewName) { this.view = viewName; }
原來(lái)這個(gè)view可以指向一個(gè)View對(duì)象,也可以指向String對(duì)象啊。View一個(gè)接口,如果看doc的話,他的實(shí)現(xiàn)類有AbstractExcelView, AbstractJasperReportsSingleFormatView, AbstractJasperReportsView, AbstractJExcelView, AbstractPdfStamperView, AbstractPdfView,AbstractTemplateView, AbstractUrlBasedView, AbstractView, AbstractXsltView, ConfigurableJasperReportsView, FreeMarkerView, InternalResourceView,JasperReportsCsvView, JasperReportsHtmlView, JasperReportsMultiFormatView, JasperReportsPdfView, JasperReportsXlsView, JstlView, RedirectView,TilesJstlView, TilesView, TilesView, VelocityLayoutView, VelocityToolboxView, VelocityView, XsltView(誠(chéng)實(shí)的說(shuō),這些View是拷doc的)。
現(xiàn)在可以知道,我們的Controller返回一個(gè)View和Model,來(lái)讓Spring框架來(lái)創(chuàng)建一個(gè)回應(yīng)。
現(xiàn)在奇怪的還有一點(diǎn),我吧view設(shè)置為字符串,Spring框架怎么處理?在ModelAndView中,如果view是一個(gè)字符串,則會(huì)將這個(gè)值交給DispatcherServlet的viewResovler來(lái)處理。記得上面提到的viewResovler了嗎?呵呵,派上用場(chǎng)了。
view的問(wèn)題解決了,然后再說(shuō)model吧。在ModelAndView添加了一些對(duì)象,Spring是怎么處理的呢?總應(yīng)該把這些對(duì)象給弄到request對(duì)象里,讓jsp頁(yè)面來(lái)使用吧。讓View使用?那么看看View接口吧:
public interface View { String getContentType(); void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception; }
render函數(shù)需要帶一個(gè)model變量。再找找view的實(shí)現(xiàn)類,看看是怎么工作的。不過(guò)view有那么多,對(duì)于一些像什么pdf啦,excel了他們都不需要在request中添加這個(gè)model。
最終呢,我們?cè)趈stlView的父類InternalResourceView中的renderMergedOutputModel函數(shù)發(fā)現(xiàn)他把model放在了request里面了。
OK,現(xiàn)在我們明白了,controller返回的modelandview交給Servlet進(jìn)行處理,來(lái)生成一個(gè)頁(yè)面。
最簡(jiǎn)單的Controller介紹完畢?,F(xiàn)在看看Spring提供的一些controller的實(shí)現(xiàn),Spring提供了很多controller的實(shí)現(xiàn),繼承的結(jié)構(gòu)如下:
org.springframework.web.servlet.mvc.AbstractController (implements org.springframework.web.servlet.mvc.Controller)
- org.springframework.web.servlet.mvc.AbstractUrlViewController
- org.springframework.web.servlet.mvc.UrlFilenameViewController
- org.springframework.web.servlet.mvc.BaseCommandController
- org.springframework.web.servlet.mvc.AbstractCommandController
- org.springframework.web.servlet.mvc.AbstractFormController
- org.springframework.web.servlet.mvc.AbstractWizardFormController
- org.springframework.web.servlet.mvc.SimpleFormController
- org.springframework.web.servlet.mvc.CancellableFormController
- org.springframework.web.servlet.mvc.ParameterizableViewController
- org.springframework.web.servlet.mvc.ServletForwardingController (implements org.springframework.beans.factory.BeanNameAware)
- org.springframework.web.servlet.mvc.ServletWrappingController (implements org.springframework.beans.factory.BeanNameAware, org.springframework.beans.factory.DisposableBean, org.springframework.beans.factory.InitializingBean)
AbstractController是Controller的第一個(gè)實(shí)現(xiàn)。其他的Controller都是繼承這個(gè)Controller的。我們先看比較重要的Controller。
先說(shuō)UrlFilenameViewController。不如我們自己來(lái)部署一個(gè)吧。
在example-servlet.xml中增加如下的配置:
<bean name="/error.do" class="org.springframework.web.servlet.mvc.UrlFilenameViewController">
</bean>
OK,當(dāng)/error.do的請(qǐng)求上來(lái)后,urlFileNameViewController將他變成/error。然后返回個(gè)View,這個(gè)view的name就是/error,然后使用viewresolver來(lái)進(jìn)行解析,可以解析成/jsp/error.jsp。
另外還有比較重要的controller是baseCommandController,將請(qǐng)求參數(shù)轉(zhuǎn)換為一個(gè)對(duì)象,并對(duì)對(duì)象參數(shù)合法性進(jìn)行驗(yàn)證。另外,SimpleFormController可以對(duì)表單進(jìn)行處理。
關(guān)于各個(gè)controller的分析。未完待續(xù)。。
posted on 2009-11-25 11:09 追求無(wú)止境 閱讀(3721) 評(píng)論(2) 編輯 收藏