欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring?MVC策略模式之MethodArgumentResolver源碼解析

 更新時間:2023年03月30日 09:00:37   作者:這堆干貨有點猛  
這篇文章主要為大家介紹了Spring?MVC策略模式之MethodArgumentResolver源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

正文  

Spring MVC 是一個基于 MVC 設(shè)計模式的Web框架,它的核心就是 DispatcherServlet,它相當于請求的中央處理器。在 DispatcherServlet 中,它使用了 MethodArgumentResolver 來解析方法參數(shù)。

       MethodArgumentResolver 采用一種策略模式,在 Handler 的方法被調(diào)用前,Spring MVC 會自動將 HTTP 請求中的參數(shù)轉(zhuǎn)換成方法參數(shù)。MethodArgumentResolver 接口的作用就是允許開發(fā)人員自定義參數(shù)解析器,以便更好地解析 HTTP 請求中的參數(shù)。

例子

       我們可以通過實現(xiàn) MethodArgumentResolver 接口來創(chuàng)建自己的參數(shù)解析器。MethodArgumentResolver 通過 supportsParameter() 這個方法用來判斷參數(shù)是否可以被當前解析器解析。如果返回 true,則調(diào)用 resolveArgument() 方法來解析參數(shù)。

下面是一個簡單的例子,演示如何實現(xiàn)一個自定義的 MethodArgumentResolver:

public class CustomArgumentResolver implements MethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().equals(CustomObject.class);
    }
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        CustomObject customObject = new CustomObject();
        customObject.setName(webRequest.getParameter("name"));
        customObject.setAge(Integer.parseInt(webRequest.getParameter("age")));
        return customObject;
    }
}

       在上面的例子中,我們實現(xiàn)了一個 CustomArgumentResolver,用來解析 CustomObject 類型的參數(shù)。supportsParameter() 方法判斷參數(shù)類型是否為 CustomObject 類型,如果是則返回true。resolveArgument() 方法用來解析參數(shù),將請求中的 "age" 和 "name" 參數(shù)設(shè)置到 CustomObject 對象中。

源碼分析

       Spring MVC 中有很多默認的參數(shù)解析器,比如 RequestParamMethodArgumentResolver、PathVariableMethodArgumentResolver、ModelMethodProcessor 等。下面我們來看一下這些解析器的源碼實現(xiàn)。

RequestParamMethodArgumentResolver:

public class RequestParamMethodArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(RequestParam.class);
    }
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        // 獲取注解
        RequestParam annotation = parameter.getParameterAnnotation(RequestParam.class);
        String paramName = annotation.value();
        String defaultValue = annotation.defaultValue();
        boolean required = annotation.required();
        String[] paramValues = webRequest.getParameterValues(paramName);
        if (paramValues == null || paramValues.length == 0) {
            if (required) {
                throw new MissingServletRequestParameterException(paramName, parameter.getParameterType().getSimpleName());
            }
            return defaultValue;
        }
        if (paramValues.length == 1) {
            return convertIfNecessary(paramValues[0], parameter.getParameterType());
        }
        return Arrays.stream(paramValues).map(value -> convertIfNecessary(value, parameter.getParameterType())).collect(Collectors.toList());
    }
}

       RequestParamMethodArgumentResolver 用來解析請求中的 @RequestParam 注解參數(shù)

supportsParameter() 方法判斷參數(shù)是否有 @RequestParam 注解,如果有則返回 true。

resolveArgument()方法解析參數(shù),獲取 RequestParam 注解的 value、defaultValue 和 required 屬性,然后根據(jù)參數(shù)名從請求中獲取參數(shù)值,最后將參數(shù)值轉(zhuǎn)換成目標類型。

PathVariableMethodArgumentResolver:

public class PathVariableMethodArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(PathVariable.class);
    }
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        PathVariable annotation = parameter.getParameterAnnotation(PathVariable.class);
        String attributeName = annotation.value();
        Map<String, String> uriTemplateVariables = (Map<String, String>) webRequest.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);
        String attributeValue = uriTemplateVariables.get(attributeName);
        return convertIfNecessary(attributeValue, parameter.getParameterType());
    }
}

       PathVariableMethodArgumentResolver 用來解析請求中的 @PathVariable 注解參數(shù)。

supportsParameter() 方法判斷參數(shù)是否有 @PathVariable 注解,如果有則返回 true。

resolveArgument() 方法解析參數(shù),獲取 @PathVariable 注解的 value 屬性,然后從請求中獲取 URI 模板變量的值,最后將變量值轉(zhuǎn)換成目標類型。

ModelMethodProcessor:

public class ModelMethodProcessor implements HandlerMethodReturnValueHandler {
    @Override
    public boolean supportsReturnType(MethodParameter returnType) {
        return Model.class.isAssignableFrom(returnType.getParameterType());
    }
    @Override
    public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
        Model model = mavContainer.getModel();
        model.addAllAttributes((Map<String, ?>) returnValue);
    }
}

用來處理 Handler 方法的返回值,并將返回值添加到 Model中。

supportsReturnType() 方法判斷返回類型是否為 Model 類型或其子類,如果是則返回 true。

handleReturnValue() 方法將返回值轉(zhuǎn)換成 Map 類型,然后將 Map 中的鍵值對添加到 Model 中。

總結(jié)

       MethodArgumentResolver 的主要作用就是將請求參數(shù)轉(zhuǎn)換為 Handler 方法的參數(shù)。在Spring MVC中,有很多默認的MethodArgumentResolver實現(xiàn),例如RequestParamMethodArgumentResolver、PathVariableMethodArgumentResolver、ModelAttributeMethodArgumentResolver 等,這些默認的 MethodArgumentResolver 實現(xiàn)可以滿足大多數(shù)場景的需求,如果需要自定義 MethodArgumentResolver 實現(xiàn),可以通過實現(xiàn) MethodArgumentResolver 接口來實現(xiàn),這些都遵循了策略模式的設(shè)計原則,具有較好的可擴展性和可維護性。

以上就是Spring MVC策略模式之MethodArgumentResolver源碼解析的詳細內(nèi)容,更多關(guān)于Spring MVC MethodArgumentResolver的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 如何使用java修改文件所有者及其權(quán)限

    如何使用java修改文件所有者及其權(quán)限

    這篇文章主要介紹了如何使用java修改文件所有者及其權(quán)限,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • IDEA快速搭建Java開發(fā)環(huán)境的教程圖解

    IDEA快速搭建Java開發(fā)環(huán)境的教程圖解

    這篇文章主要介紹了IDEA如何快速搭建Java開發(fā)環(huán)境,本文通過圖文并茂的形式給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-11-11
  • 深入分析Java異常

    深入分析Java異常

    本篇文章給大家詳細分享了關(guān)于Java異常的相關(guān)知識點,對此有需要的朋友跟著學習下吧。
    2018-05-05
  • JAVA使用動態(tài)代理對象進行敏感字過濾代碼實例

    JAVA使用動態(tài)代理對象進行敏感字過濾代碼實例

    這篇文章主要介紹了JAVA使用動態(tài)代理對象進行敏感字過濾代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-09-09
  • SpringBoot整合PostgreSQL的示例代碼

    SpringBoot整合PostgreSQL的示例代碼

    本文主要介紹了SpringBoot整合PostgreSQL的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-07-07
  • Java動態(tài)代理和反射機制詳解

    Java動態(tài)代理和反射機制詳解

    這篇文章主要介紹了Java動態(tài)代理和反射機制,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-03-03
  • JAVA JVM面試題總結(jié)

    JAVA JVM面試題總結(jié)

    JVM 可以屏蔽與具體操作系統(tǒng)平臺相關(guān)的信息,使 Java 程序只需生成在 Java 虛擬機上運行的目標代碼,就可以在不同的平臺上運行。這篇文章主要介紹了JAVA JVM面試題總結(jié),大家可以參考一下
    2021-08-08
  • Java執(zhí)行cmd命令的舉例與注意事項

    Java執(zhí)行cmd命令的舉例與注意事項

    Java應用程序主要是通過Runtime和Process兩個類來執(zhí)行cmd命令,下面這篇文章主要給大家介紹了關(guān)于Java執(zhí)行cmd命令的方法與注意事項,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-02-02
  • 如何使用JCTools實現(xiàn)Java并發(fā)程序

    如何使用JCTools實現(xiàn)Java并發(fā)程序

    這篇文章主要介紹了如何使用JCTools實現(xiàn)Java并發(fā)程序,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下
    2021-03-03
  • Spring+Http請求+HttpClient實現(xiàn)傳參

    Spring+Http請求+HttpClient實現(xiàn)傳參

    這篇文章主要介紹了Spring+Http請求+HttpClient實現(xiàn)傳參,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-03-03

最新評論