中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SpringBoot如何自定義參數解析器

發布時間:2021-06-22 17:03:12 來源:億速云 閱讀:222 作者:chen 欄目:大數據

本篇內容主要講解“SpringBoot如何自定義參數解析器”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“SpringBoot如何自定義參數解析器”吧!

SpringMVC提供了各種姿勢的http參數解析支持,從前面的GET/POST參數解析篇也可以看到,加一個@RequsetParam注解就可以將方法參數與http參數綁定,看到這時自然就會好奇這是怎么做到的,我們能不能自己定義一種參數解析規則呢?

本文將介紹如何實現自定義的參數解析,并讓其生效

<!-- more -->

I. 環境搭建

首先得搭建一個web應用才有可能繼續后續的測試,借助SpringBoot搭建一個web應用屬于比較簡單的活;

創建一個maven項目,pom文件如下

<parent>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-parent</artifactid>
    <version>2.1.7</version>
    <relativepath /> <!-- lookup parent from update -->
</parent>

<properties>
    <project.build.sourceencoding>UTF-8</project.build.sourceencoding>
    <project.reporting.outputencoding>UTF-8</project.reporting.outputencoding>
    <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-starter-web</artifactid>
    </dependency>
</dependencies>

<build>
    <pluginmanagement>
        <plugins>
            <plugin>
                <groupid>org.springframework.boot</groupid>
                <artifactid>spring-boot-maven-plugin</artifactid>
            </plugin>
        </plugins>
    </pluginmanagement>
</build>
<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

II. 自定義參數解析器

對于如何自定義參數解析器,一個較推薦的方法是,先搞清楚springmvc接收到一個請求之后完整的處理鏈路,然后再來看在什么地方,什么時機,來插入自定義參數解析器,無論是從理解還是實現都會簡單很多。遺憾的是,本篇主要目標放在的是使用角度,所以這里只會簡單的提一下參數解析的鏈路,具體的深入留待后續的源碼解析

1. 參數解析鏈路

http請求流程圖,來自 SpringBoot是如何解析HTTP參數的

SpringBoot如何自定義參數解析器

既然是參數解析,所以肯定是在方法調用之前就會被觸發,在Spring中,負責將http參數與目標方法參數進行關聯的,主要是借助org.springframework.web.method.support.HandlerMethodArgumentResolver類來實現

/**
 * Iterate over registered {@link HandlerMethodArgumentResolver}s and invoke the one that supports it.
 * @throws IllegalStateException if no suitable {@link HandlerMethodArgumentResolver} is found.
 */
@Override
@Nullable
public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
		NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {

	HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);
	if (resolver == null) {
		throw new IllegalArgumentException("Unknown parameter type [" + parameter.getParameterType().getName() + "]");
	}
	return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
}

上面這段核心代碼來自org.springframework.web.method.support.HandlerMethodArgumentResolverComposite#resolveArgument,主要作用就是獲取一個合適的HandlerMethodArgumentResolver,實現將http參數(webRequest)映射到目標方法的參數上(parameter)

所以說,實現自定義參數解析器的核心就是實現一個自己的HandlerMethodArgumentResolver

2. HandlerMethodArgumentResolver

實現一個自定義的參數解析器,首先得有個目標,我們在get參數解析篇里面,當時遇到了一個問題,當傳參為數組時,定義的方法參數需要為數組,而不能是List,否則無法正常解析;現在我們則希望能實現這樣一個參數解析,以支持上面的場景

為了實現上面這個小目標,我們可以如下操作

a. 自定義注解ListParam

定義這個注解,主要就是用于表明,帶有這個注解的參數,希望可以使用我們自定義的參數解析器來解析;

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ListParam {
    /**
     * Alias for {@link #name}.
     */
    @AliasFor("name") String value() default "";

    /**
     * The name of the request parameter to bind to.
     *
     * @since 4.2
     */
    @AliasFor("value") String name() default "";
}
b. 參數解析器ListHandlerMethodArgumentResolver

接下來就是自定義的參數解析器了,需要實現接口HandlerMethodArgumentResolver

public class ListHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(ListParam.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
            NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        ListParam param = parameter.getParameterAnnotation(ListParam.class);
        if (param == null) {
            throw new IllegalArgumentException(
                    "Unknown parameter type [" + parameter.getParameterType().getName() + "]");
        }

        String name = "".equalsIgnoreCase(param.name()) ? param.value() : param.name();
        if ("".equalsIgnoreCase(name)) {
            name = parameter.getParameter().getName();
        }
        String ans = webRequest.getParameter(name);
        if (ans == null) {
            return null;
        }

        String[] cells = StringUtils.split(ans, ",");
        return Arrays.asList(cells);
    }
}

上面有兩個方法:

  • supportsParameter就是用來表明這個參數解析器適不適用

    • 實現也比較簡單,就是看參數上有沒有前面定義的ListParam注解

  • resolveArgument 這個方法就是實現將http參數粗轉換為目標方法參數的具體邏輯

    • 上面主要是為了演示自定義參數解析器的過程,實現比較簡單,默認只支持List<string>

3. 注冊

上面雖然實現了自定義的參數解析器,但是我們需要把它注冊到HandlerMethodArgumentResolver才能生效,一個簡單的方法如下

@SpringBootApplication
public class Application extends WebMvcConfigurationSupport {

    @Override
    protected void addArgumentResolvers(List<handlermethodargumentresolver> argumentResolvers) {
        argumentResolvers.add(new ListHandlerMethodArgumentResolver());
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }
}

4. 測試

為了驗證我們的自定義參數解析器ok,我們開兩個對比的rest服務

@RestController
@RequestMapping(path = "get")
public class ParamGetRest {
    /**
     * 自定義參數解析器
     *
     * @param names
     * @param age
     * @return
     */
    @GetMapping(path = "self")
    public String selfParam(@ListParam(name = "names") List<string> names, Integer age) {
        return names + " | age=" + age;
    }

    @GetMapping(path = "self2")
    public String selfParam2(List<string> names, Integer age) {
        return names + " | age=" + age;
    }
}

演示demo如下,添加了ListParam注解的可以正常解析,沒有添加注解的會拋異常

SpringBoot如何自定義參數解析器

到此,相信大家對“SpringBoot如何自定義參數解析器”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

原阳县| 鄂伦春自治旗| 巴林左旗| 潞城市| 海原县| 宁陵县| 岫岩| 沅陵县| 昌图县| 礼泉县| 新安县| 天峨县| 航空| 五常市| 庆安县| 三门峡市| 深水埗区| 都兰县| 关岭| 固原市| 施甸县| 玛沁县| 巫山县| 曲阜市| 雅安市| 中山市| 双鸭山市| 交口县| 湘西| 濮阳市| 深水埗区| 洪湖市| 东辽县| 盐源县| 大同市| 彩票| 沂南县| 雅安市| 牡丹江市| 蕉岭县| 中江县|