在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問(wèn)答/Java/ SpringMVC的Controller是如何將參數(shù)和前端傳來(lái)的數(shù)據(jù)一一對(duì)應(yīng)的

SpringMVC的Controller是如何將參數(shù)和前端傳來(lái)的數(shù)據(jù)一一對(duì)應(yīng)的

Spring接收前端傳來(lái)的參數(shù)之后,是如何把前端參數(shù)對(duì)應(yīng)到方法里的參數(shù)的?
比如

public String hello(String hello, @RequestParam(value = "world") String world, String end) {
    return hello + world + end;
}

這個(gè)方法,假如url是http://localhost:8080/hello?hello=hi&word=spring&end=!
那么spring就可以把hello方法里的hello,world,end一一對(duì)應(yīng)上。
world這個(gè)參數(shù)能對(duì)應(yīng)上還可以理解,因?yàn)橛袀€(gè)注解@RequestParam里寫(xiě)了參數(shù)名。
但是hello`,end是如何找到對(duì)應(yīng)參數(shù)的?java在編譯之后他的參數(shù)名就沒(méi)了,spring如何知道第一個(gè)參數(shù)是hello,第三個(gè)參數(shù)是end的?

我問(wèn)題的意思是...spring是如何實(shí)現(xiàn)參數(shù)的對(duì)應(yīng)的?如何知道hello()方法中的參數(shù)'hello,end'這兩個(gè)的參數(shù)名字的,java編譯之后就沒(méi)有參數(shù)名字了

回答
編輯回答
爛人
2018年7月4日 21:12
編輯回答
舊言

@RequestParam

位于RequestParamMethodArgumentResolver和RequestParamMapMethodArgumentResolver 中

2017年4月11日 08:50
編輯回答
眼雜

spring對(duì)request參數(shù)做了處理,用request中的參數(shù)去匹配方法的參數(shù),如果name一樣,就會(huì)把值傳過(guò)去,好像是跟順序沒(méi)關(guān)系的,這點(diǎn)你可以試一下。
而你參數(shù)上的注解,是用來(lái)匹配name值不同的情況的,如果請(qǐng)求的參數(shù)名稱和方法參數(shù)名稱不同,就可以用這個(gè)注解。

添加一個(gè)攔截器,在映射這個(gè)方法之前,對(duì)這個(gè)方法進(jìn)行反射處理,獲取方法的參數(shù)及名稱,然后在用發(fā)射調(diào)用這個(gè)方法。差不多是這樣,具體要看spring源碼才能知道。

2018年1月18日 16:34
編輯回答
熟稔

你把名字改了就知道了

2017年4月16日 00:30
編輯回答
怪痞

大家都沒(méi)理解我問(wèn)的問(wèn)題,可能是我提問(wèn)的技巧還不是很好,不過(guò)我已經(jīng)找到答案了。
我想問(wèn)的是假如在Controller里的方法參數(shù)沒(méi)有@RequestParam注解的時(shí)候,Spring是如何通過(guò)反射調(diào)用這個(gè)方法的,因?yàn)閖ava的反射是無(wú)法獲取參數(shù)名字的,無(wú)法獲取參數(shù)名字就以為著無(wú)法把前端傳來(lái)的參數(shù)找到方法中正確的參數(shù)。
現(xiàn)在我找到答案了:
在Spring中的類DefaultParameterNameDiscoverer (<version>2.0.2.RELEASE</version>):

public class DefaultParameterNameDiscoverer extends PrioritizedParameterNameDiscoverer {

    private static final boolean kotlinPresent =
            ClassUtils.isPresent("kotlin.Unit", DefaultParameterNameDiscoverer.class.getClassLoader());

    public DefaultParameterNameDiscoverer() {
        if (kotlinPresent) {
            addDiscoverer(new KotlinReflectionParameterNameDiscoverer());
        }
        addDiscoverer(new StandardReflectionParameterNameDiscoverer());
        addDiscoverer(new LocalVariableTableParameterNameDiscoverer());
    }

}

這個(gè)類是設(shè)置查找參數(shù)名方法的類,這里有三種
1.KotlinReflectionParameterNameDiscoverer:
看代碼是判定是否為Kotlin,如果是就用這種,對(duì)于Kotlin我也不熟就沒(méi)有細(xì)看
2.StandardReflectionParameterNameDiscoverer:
這是用java原生自帶的反射原理獲取參數(shù)名字

private String[] getParameterNames(Parameter[] parameters) {
        String[] parameterNames = new String[parameters.length];
        for (int i = 0; i < parameters.length; i++) {
            Parameter param = parameters[i];
            if (!param.isNamePresent()) {
                return null;
            }
            parameterNames[i] = param.getName();
        }
        return parameterNames;
    }

3.LocalVariableTableParameterNameDiscoverer
這是spring通過(guò)asm讀取class字節(jié)碼來(lái)獲取方法的參數(shù)名字,具體的解釋可以查看資料

所以Spring實(shí)際上是通過(guò)反射或者字節(jié)碼讀取獲取方法的參數(shù)的名字的。
另外我這個(gè)Spring的源碼2.0.2.RELEASE,由于2.X.X以上的版本要求jdk環(huán)境是1.8以上。在2.X.X一下的版本DefaultParameterNameDiscoverer類會(huì)先判斷環(huán)境是否是1.8以上,如果是,在會(huì)調(diào)用
StandardReflectionParameterNameDiscoverer這個(gè)原生反射查找參數(shù)名的類,因?yàn)檫@個(gè)方法要jdk1.8以后才支持。

2017年11月27日 07:04