app開發制作過程中,使用(yòng)JAVA注解方式,實現權限功能開發

發布時(shí)間:2022-05-18 10:56:55 作者:King 來(lái)源:本站 浏覽量(4330) 點贊(87)
摘要:app開發制作過程中,app端請求後端數據,每個(gè)方法都要判斷該用(yòng)戶是否登陸,這(zhè)樣就會造成代碼重複,不易維護,對(duì)于該問題,閃端講解一種更方便的(de)方法,希望能幫助到大(dà)家!SpringBoot 參數解析 HandlerMethodArgumentResolverSpringMVC提供了(le)各種姿勢的(de)http參數解析支持,GET/POST參數解析篇也(yě)可(kě)以看到,加一個(gè)@RequestParam注

app開發制作過程中,app端請求後端數據,每個(gè)方法都要判斷該用(yòng)戶是否登陸,這(zhè)樣就會造成代碼重複,不易維護,對(duì)于該問題,閃端講解一種更方便的(de)方法,希望能幫助到大(dà)家!


SpringBoot 參數解析 HandlerMethodArgumentResolver

SpringMVC提供了(le)各種姿勢的(de)http參數解析支持,GET/POST參數解析篇也(yě)可(kě)以看到,加一個(gè)@RequestParam注解就可(kě)以将方法參數與http參數綁定,看到這(zhè)時(shí)自然就會好奇這(zhè)是怎麽做(zuò)到的(de),我們能不能自己定義一種參數解析規則呢(ne)?

将介紹如何實現自定義的(de)參數解析,并讓其生效

I. 環境搭建

首先得(de)搭建一個(gè)web應用(yòng)才有可(kě)能繼續後續的(de)測試,借助SpringBoot搭建一個(gè)web應用(yòng)屬于比較簡單的(de)活;

創建一個(gè)maven項目,pom文件如下(xià)

<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. 自定義參數解析器

對(duì)于如何自定義參數解析器,一個(gè)較推薦的(de)方法是,先搞清楚springmvc接收到一個(gè)請求之後完整的(de)處理(lǐ)鏈路,然後再來(lái)看在什(shén)麽地方,什(shén)麽時(shí)機,來(lái)插入自定義參數解析器,無論是從理(lǐ)解還(hái)是實現都會簡單很多(duō)。遺憾的(de)是,本篇主要目标放在的(de)是使用(yòng)角度,所以這(zhè)裏隻會簡單的(de)提一下(xià)參數解析的(de)鏈路,具體的(de)深入留待後續的(de)源碼解析

1. 參數解析鏈路

http請求流程圖:


app開發制作過程中,使用(yòng)JAVA注解方式,實現權限功能開發


既然是參數解析,所以肯定是在方法調用(yòng)之前就會被觸發,在Spring中,負責将http參數與目标方法參數進行關聯的(de),主要是借助org.springframework.web.method.support.HandlerMethodArgumentResolver類來(lái)實現


/**
 * 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);
}



上面這(zhè)段核心代碼來(lái)自org.springframework.web.method.support.HandlerMethodArgumentResolverComposite#resolveArgument,主要作用(yòng)就是獲取一個(gè)合适的(de)HandlerMethodArgumentResolver,實現将http參數(webRequest)映射到目标方法的(de)參數上(parameter)


apple-system, system-ui, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Arial; background-color: rgb(255, 255, 255);">所以說,實現自定義參數解析器的(de)核心就是實現一個(gè)自己的(de)HandlerMethodArgumentResolver


2. HandlerMethodArgumentResolver

實現一個(gè)自定義的(de)參數解析器,首先得(de)有個(gè)目标,我們在get參數解析,當時(shí)遇到了(le)一個(gè)問題,當傳參爲數組時(shí),定義的(de)方法參數需要爲數組,而不能是List,否則無法正常解析;現在我們則希望能實現這(zhè)樣一個(gè)參數解析,以支持上面的(de)場(chǎng)景

爲了(le)實現上面這(zhè)個(gè)小目标,我們可(kě)以如下(xià)操作

a. 自定義注解ListParam

定義這(zhè)個(gè)注解,主要就是用(yòng)于表明(míng),帶有這(zhè)個(gè)注解的(de)參數,希望可(kě)以使用(yòng)我們自定義的(de)參數解析器來(lái)解析;

@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

接下(xià)來(lái)就是自定義的(de)參數解析器了(le),需要實現接口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);
    }
}

上面有兩個(gè)方法:


supportsParameter就是用(yòng)來(lái)表明(míng)這(zhè)個(gè)參數解析器适不适用(yòng)

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

resolveArgument 這(zhè)個(gè)方法就是實現将http參數粗轉換爲目标方法參數的(de)具體邏輯

  • 上面主要是爲了(le)演示自定義參數解析器的(de)過程,實現比較簡單,默認隻支持List<String>

3. 注冊

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

@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. 測試

爲了(le)驗證我們的(de)自定義參數解析器ok,我們開兩個(gè)對(duì)比的(de)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;
    }
}

如您有開發需求,可(kě)聯系閃端,我們專注于微信小程序開發、外賣、社區(qū)團購(gòu)、分(fēn)銷商城(chéng)、分(fēn)銷系統、量身定制開發、原生android定制、opencv人(rén)臉識别項目、網站建設等互聯網平台業務!

微信

掃一掃,關注我們

感興趣嗎?

歡迎聯系我們,我們願意爲您解答(dá)任何有關網站疑難問題!

【如有開發需求】那就聯系我們吧

搜索千萬次不如咨詢1次

承接:網站建設,手機網站,響應式網站,小程序開發,原生android開發等業務

立即咨詢 16605125102