上次大概寫了個可以解決velocity 多視圖的東西。
但是實際運用過程中又到處找了些資料看了下。這里
小計下:
DispatcherServlet解析過程:
..1..HandlerMapping.getPageHandle
public class SpringMvcExtendHandlerMapping extends WebApplicationObjectSupport
implements HandlerMapping, Ordered{
..2..HandlerMapping.getPageHandle 內部就是new HandlerExecutionChain
handle==》new IPageHandle自定義(Controller)(-->內部new IWebPage)
HandlerAdapter==》new List<HandlerAdapter>(各種Handler攔截器)
這里是各種分發的核心部分,handle將是整個http請求從開始到結束的持有者,比如mvc 的許多頁面分發都在這里第一次處理
比如new 那個control 啊都在這里處理
..3..HandlerAdapter.supports==》驗證 handle是否是 instanceof IWebPage
spring mvc 靠這個來識別用那個HandlerInterceptorAdapter 來注入屬性
..4..HandlerInterceptorAdapter.preHandle 視圖解析前==》把request resopnse 放到handle里面
這個實際被大多人用來驗證登錄啊啥的,我這里主要是把request response 放到自己的IWebPage里面
..5..HandlerAdapter.handle 攔截器對頁面請求進行過濾,mvc框架在這里根據你的配置對ModelAndView進行各種屬性填入
也是modelAndView生成的地方
我們見到的各種Annotation 都在這里這里注入,new 出不同ModelAndView
..5.1..DispatcherServlet.applyDefaultViewName 這里進行view的路徑尋找
估計使用來處理Servletbean的,沒有細看
我將其 理解為spring mvc 將根據ModelAndView viewname找到真正的模板解析器識別的路徑
..6..HandlerInterceptorAdapter.postHandle --》開始調用對應的 前面new 好的 IWebPage
這個可以理解為dopost doget的body
這里比較特殊就是Annotation的各種返回
我了在這里將action分發到對應的IWebPage的方法上去,原理借鑒了Annotation的各種
我的viewname也是在這里根據自己需要自己弄進入的,主要是通過后綴來分別不同模板引擎
..7..DispatcherServlet.processDispatchResult--》 找視圖
=> DispatcherServlet.render 視圖渲染
==>DispatcherServlet.resolveViewName 在viewResolvers找匹配的視圖,//這個多視圖的可以搞的地方,下面的view就是這里來的
==》ModelAndView.getView().render ==>真實的dopost ,doget 的輸出
..8..HandlerInterceptorAdapter.afterCompletion--》頁面全部完成了。
下面是具體的實現的思路
1、HandlerMapping 用於定位具體的Controller類我習慣叫pagehandle,我認為是模塊分發modelfactory
eg:implement 這個是比較標准,我繼承過其他的HandlerMapping 但是實際自己使用還是從接口開始更好實現
public class SpringMvcExtendHandlerMapping extends WebApplicationObjectSupport implements HandlerMapping, Ordered{
這里可以通過從新定義:
public HandlerExecutionChain getHandler(HttpServletRequest request)
可以實現 對應的control分發
eg:
String requestPath = ResourceUtil.getRequestPath(request);
if(requestPath.contains("mytest")
{
//這個handle是比較啰嗦的東西,在mvc 這個東西就是Controller類,自定義么可以用但是需要配套HandlerAdapter
HandlerExecutionChain back = new HandlerExecutionChain(handle);
//這里是自定義的攔截器,通過配置文件可以,但是如果多HandlerInterceptorAdapter 你會發現各種莫名弄麻煩,
//不然自己把自己的用的上的直接綁上去更好用
back.addInterceptor(new SpringMvcExtendHandlerInterceporAdapter());
}
2、HandlerInterceptorAdapter。。 這個可以理解為頁面分發pagefactory,自己可以寫各種不同頁面分發
public class SpringMvcExtendHandlerInterceptorAdapter extends
HandlerInterceptorAdapter {
spring mvc 沒有在這里多做什么,基本都是留給用戶亂搞的
我頁面分發也是在這里搞的
這個東西么網上比較多,就是3個方法的使用
preHandle--》這里可以初始化你自己的handle(IWebPage)
postHandle--》這里可以識別action進行頁面處理
afterCompletion--》這里么,統計下訪量啊,注銷下request,response
需要注意的是
DispatcherServlet 用的for 循環preHandle 只要有一個返回false 就不繼續了,弄這個弄眼睛都花了
所以建議如果你程序要么只有一個HandlerInterceptorAdapter,要么就指定好對應的HandlerInterceptorAdapter
eg:在xml文件中用mvc標簽
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**" /><!--這里老老實實的過濾路徑--> <bean class="org.jeecgframework.core.interceptors.EncodingInterceptor" /> </mvc:interceptor> </mvc:interceptors>
eg:要么在你選擇的HandlerMapping 配置文件中指定
eg:要么像我直接寫死在HandlerMapping中
不要直接<bean class=""/>
3、HandlerAdapter
public class SpringMvcExtendHandlerAdapter implements org.springframework.web.servlet.HandlerAdapter{
一個共同參數
Object handler //這個對應HandlerMapping handle ,這個搞的我頭都是大的
備注:HandlerExecutionChain里面的handle 就是這個了
這個里面三個方法
getLastModified 自己看下頁面是否是二次請求
handle 這個用於方法在 HandlerInterceptorAdapter 的preHandle后,posthandle 之前,spring mvc用來找對應的controller
supports 驗證傳進來的handle 是否符合modelview 是否是當前HandlerAdapter 可以處理的
這里
4、SpringMvcExtendViewResolver
public class SpringMvcExtendViewResolver extends AbstractCachingViewResolver implements Ordered{
這個東西是springmvc 用來區分用那個視圖解析器的
protected View loadView(String viewName, Locale locale) throws Exception
其中的viewname 就是DispatcherServlet.applyDefaultViewName這里處理返回的viewresolver能識別的路徑
我弄的spring mvc 多視圖就是靠這個弄的。
配置文件的問題。。
比較特殊的是
HandlerMapping 這個小屁
如果你直接<bean class="com.cnynld.web.tpl.springmvc.SpringMvcExtendHandlerMapping">
springmvc 會認為只用這個而不會將着2個東西啟動起來莫名的很,各種Annotation都起作用,把我瓜的調試的暈了
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
<!-- 自定義handlemapping -->
<bean class="com.cnynld.web.tpl.springmvc.SpringMvcExtendHandlerMapping">
<property name="order" value="0"/>
<property name="pageHandleMapping">
<map>
<entry key="vm1/" >
<bean id="APageHandle" class="com.cnynld.web.tpl.test.APageHandle"/>
</entry>
<entry key="vm2/" >
<bean id="DefaultPageHandle" class="com.cnynld.web.tpl.test.DefaultPageHandle"/>
</entry>
</map>
</property>
</bean>
<!-- 啟動mvc Annotation mapping -->
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<!-- 啟動mvc Annotation handleadapter -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
<!-- 自定義mapping 對應的 handleadapter -->
<bean class="com.cnynld.web.tpl.springmvc.SpringMvcExtendHandlerAdapter"/>
nbsp;這里進行view的路徑尋找
