spring mvc 自定義Handlermapping


上次大概寫了個可以解決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的路徑尋找


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM