亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringMVC的處理器適配器-HandlerAdapter的用法及說明

 更新時間:2023年12月26日 15:02:40   作者:huangyaa729  
這篇文章主要介紹了SpringMVC的處理器適配器-HandlerAdapter的用法及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

SpringMVC處理器適配器HandlerAdapter用法

如題:

今天看spring源碼解析這本書時,看到了這個地方,對于不同HandlerAdapter的使用場景有的困惑,主要還是沒見過,因為大多數(shù)面向的Controller類型的HandlerAdapter;

HandlerAdapter目前最常見的主要為

1、SimpleControllerHandlerAdapter、HttpRequestHandlerAdapter 、AnnotationMethodHandlerAdapter (已過時),這三個是默認的;如果沒有指明新的適配器時,會從這三個中間選擇;

2、SimpleServletHandlerAdapter目前很少用到,也不是默認的適配器;

3、RequestMappingHandlerAdapter這個應(yīng)該是目前springMVC主要采用的,針對方法級的映射匹配處理。

由HandlerAdapter的實現(xiàn)類可知:映射匹配的處理器handler包括三個類型Controller、HttpRequestHandler、Servlet,但后兩個的應(yīng)用場景與使用方式我卻沒有見到過,經(jīng)過一番查找,特做一個總結(jié)以供以后參考:

1、SimpleControllerHandlerAdapter主要是針對實現(xiàn)Controller接口的handler進行適配,配置方式在書中可見;

2、SimpleServletHandlerAdapter主要是針對實現(xiàn)Servlet接口的handler進行適配,配置方式跟普通的Controller類似,如下所示:

spring配置文件中bean的配置如下:

/** 采用BeanNameUrlHandlerMapping類進行路徑映射匹配**/
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
 <bean name="/demo.do" class="com.demo.DemoServlet"/>  

對應(yīng)的Bean實現(xiàn)類為

public class DemoServlet extends HttpServlet{  
.......
}

3、HttpRequestHandlerAdapter 主要是針對實現(xiàn)HttpRequestHandler接口的handler進行適配;

HTTP請求處理器適配器僅僅支持對HTTP請求處理器的適配。它簡單的將HTTP請求對象和響應(yīng)對象傳遞給HTTP請求處理器的實現(xiàn),它并不需要返回值。它主要應(yīng)用在基于HTTP的遠程調(diào)用的實現(xiàn)上。

配置應(yīng)該與上述相同,從SpringMvc自帶的實現(xiàn)類來說,主要用于轉(zhuǎn)發(fā)或者靜態(tài)資源的加載,對應(yīng)的實現(xiàn)類為DefaultServletHttpRequestHandler和ResourceHttpRequestHandler

淺談HandlerAdapter

HandlerAdapter顧名思義就是一個適配器,(肯定也采用了適配器模式這里不做過多的解釋),那么它的主要作用是什么呢?

HandlerMapping存儲了所有都請求映射,請求過來找到相應(yīng)的請求映射后,返回給我們一個Handler

看這里的代碼:

@Nullable
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
    if (this.handlerMappings != null) {
        Iterator var2 = this.handlerMappings.iterator();

        while(var2.hasNext()) {
            HandlerMapping mapping = (HandlerMapping)var2.next();
            HandlerExecutionChain handler = mapping.getHandler(request);
            if (handler != null) {
                return handler;
            }
        }
    }

    return null;
}

這里是DispacherServlet的核心控制方法。

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        boolean multipartRequestParsed = false;
        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
 
        try {
            try {
                ModelAndView mv = null;
                Object dispatchException = null;
 
                try {
                    processedRequest = this.checkMultipart(request);
                    multipartRequestParsed = processedRequest != request;
                    mappedHandler = this.getHandler(processedRequest);
                    if (mappedHandler == null) {
                        this.noHandlerFound(processedRequest, response);
                        return;
                    }
 
                    HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
                    String method = request.getMethod();
                    boolean isGet = HttpMethod.GET.matches(method);
                    if (isGet || HttpMethod.HEAD.matches(method)) {
                        long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                        if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
                            return;
                        }
                    }
 
                    if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                        return;
                    }
 
                    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
                    if (asyncManager.isConcurrentHandlingStarted()) {
                        return;
                    }
 
                    this.applyDefaultViewName(processedRequest, mv);
                    mappedHandler.applyPostHandle(processedRequest, response, mv);
                } catch (Exception var20) {
                    dispatchException = var20;
                } catch (Throwable var21) {
                    dispatchException = new NestedServletException("Handler dispatch failed", var21);
                }
 
                this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
            } catch (Exception var22) {
                this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
            } catch (Throwable var23) {
                this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
            }
 
        } finally {
            if (asyncManager.isConcurrentHandlingStarted()) {
                if (mappedHandler != null) {
                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                }
            } else if (multipartRequestParsed) {
                this.cleanupMultipart(processedRequest);
            }
 
        }
    }

我們拿到Handler之后呢?

接著代碼往下走我們可以看到這樣一行代碼

HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());

這一步就是講我們的Handler進行一個HandlerAdapter的適配解析,我們繼續(xù)代碼跟進

public interface HandlerAdapter {
    //如果當前支持當前handler就執(zhí)行handler方法
    boolean supports(Object handler);
 
    @Nullable
    ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
 
    /** @deprecated */
    @Deprecated
    long getLastModified(HttpServletRequest request, Object handler);
}

我們知道它采用的適配器模式

protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
    if (this.handlerAdapters != null) {
        Iterator var2 = this.handlerAdapters.iterator();

        while(var2.hasNext()) {
            HandlerAdapter adapter = (HandlerAdapter)var2.next();
            if (adapter.supports(handler)) {
                return adapter;
            }
        }
    }

    throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}

DispacherServlet中這個方法,就是一個迭代器,給handler找一個適配器,那這一步到底是要做什么呢?

在HandlerAdapter中有四個實現(xiàn)類,分別處理不同Handler我們看一下我們最常用的HttpRequestHandlerAdapter

public boolean supports(Object handler) {
    return handler instanceof HttpRequestHandler;
}

里面就是去判斷了,當前handler是不是HttpRequestHandler類型,其實在我們確認號類型的時候,handler經(jīng)過RequestMappingHandlerMapping?,返回的就已經(jīng)是這個類型的了。

找到適配器之后啊,就是開始參數(shù)解析了

String method = request.getMethod();
boolean isGet = HttpMethod.GET.matches(method);
if (isGet || HttpMethod.HEAD.matches(method)) {
    long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
    if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
        return;
    }
}

核心在這里,利用的HandlerAdapter,也就是剛才找到的適配器,和目標方法傳進去,執(zhí)行目標方法。?

執(zhí)行完上面代碼,就是判斷了一下是不是get請求,HEAD這個不是由我們 去處理的。

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

上面這行代碼去執(zhí)行的目標方法。

到這里基本是完成了HandlerAdapter的一個準備工作,找到適配的HandlerAdapter之后,還要進行相應(yīng)的參數(shù)解析啊。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 全方位解析key值不確定的json數(shù)據(jù)

    全方位解析key值不確定的json數(shù)據(jù)

    這篇文章主要介紹了全方位解析key值不確定的json數(shù)據(jù),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • Java Online Exam在線考試系統(tǒng)的實現(xiàn)

    Java Online Exam在線考試系統(tǒng)的實現(xiàn)

    讀萬卷書不如行萬里路,只學(xué)書上的理論是遠遠不夠的,只有在實戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+springboot+vue+jsp+mysql+maven實現(xiàn)Online Exam在線考試系統(tǒng),大家可以在過程中查缺補漏,提升水平
    2021-11-11
  • 迅速學(xué)會@ConfigurationProperties的使用操作

    迅速學(xué)會@ConfigurationProperties的使用操作

    這篇文章主要介紹了迅速學(xué)會@ConfigurationProperties的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • java實現(xiàn)微信紅包 拼手氣紅包

    java實現(xiàn)微信紅包 拼手氣紅包

    這篇文章主要為大家詳細介紹了java實現(xiàn)微信紅包,拼手氣紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • Springboot詳解如何實現(xiàn)SQL注入過濾器過程

    Springboot詳解如何實現(xiàn)SQL注入過濾器過程

    這篇文章主要介紹了基于springboot實現(xiàn)SQL注入過濾器,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2022-06-06
  • springcloud中Feign超時提示Read timed out executing POST的問題及解決方法

    springcloud中Feign超時提示Read timed out executing

    Feign接口調(diào)用分兩層,Ribbon的調(diào)用和Hystrix調(diào)用,理論上設(shè)置Ribbon的時間即可,但是Ribbon的超時時間和Hystrix的超時時間需要結(jié)合起來,這篇文章給大家介紹springcloud之Feign超時提示Read timed out executing POST問題及解決方法,感興趣的朋友一起看看吧
    2024-01-01
  • 分布式服務(wù)Dubbo+Zookeeper安全認證實例

    分布式服務(wù)Dubbo+Zookeeper安全認證實例

    下面小編就為大家分享一篇分布式服務(wù)Dubbo+Zookeeper安全認證實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • Java中的MapStruct知識點總結(jié)

    Java中的MapStruct知識點總結(jié)

    這篇文章主要介紹了Java中的MapStruct知識點總結(jié),MapStruct是一個Java注解處理器,用于生成類型安全的映射代碼,它可以自動處理源對象和目標對象之間的映射,減少了手動編寫重復(fù)的映射代碼的工作量,需要的朋友可以參考下
    2023-10-10
  • 在SpringBoot當中使用Thymeleaf視圖解析器的詳細教程

    在SpringBoot當中使用Thymeleaf視圖解析器的詳細教程

    Thymeleaf是一款開源的模板引擎,它允許前端開發(fā)者使用HTML與XML編寫動態(tài)網(wǎng)頁,hymeleaf的主要特點是將表達式語言嵌入到HTML結(jié)構(gòu)中,它支持Spring框架,使得在Spring MVC應(yīng)用中集成非常方便,本文給大家介紹了在SpringBoot當中使用Thymeleaf視圖解析器的詳細教程
    2024-09-09
  • springboot2.3 整合mybatis-plus 高級功能(圖文詳解)

    springboot2.3 整合mybatis-plus 高級功能(圖文詳解)

    這篇文章主要介紹了springboot2.3 整合mybatis-plus 高級功能,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08

最新評論