激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Struts2源碼分析之ParametersInterceptor攔截器

Struts2源碼分析之ParametersInterceptor攔截器

2019-07-04 16:57chen_hao Java教程

這篇文章主要介紹了Struts2源碼分析之ParametersInterceptor攔截器,ParametersInterceptor攔截器其主要功能是把ActionContext中的請求參數設置到ValueStack中,,需要的朋友可以參考下

前言

ParametersInterceptor攔截器其主要功能是把ActionContext中的請求參數設置到ValueStack中,如果棧頂是當前Action則把請求參數設置到了Action中,如果棧頂是一個model(Action實現了ModelDriven接口)則把參數設置到了model中。

下面是該攔截器的doIntercept方法源碼:

@Override
public String doIntercept(ActionInvocation invocation) throws Exception {
Object action = invocation.getAction();//獲取當前執行的Action對象
if (!(action instanceof NoParameters)) {//判斷Action是否實現了NoParameters接口,實現該接口表示該Action沒有任何請求參數
ActionContext ac = invocation.getInvocationContext();//獲取ActionContext對象
final Map<String, Object> parameters = retrieveParameters(ac);//獲取請求參數Map
//省略...
if (parameters != null) {//如果請求參數不為null
Map<String, Object> contextMap = ac.getContextMap();//獲取ActionContext內部的context Map,即OgnlContext對象
try {
//省略...
ValueStack stack = ac.getValueStack();//獲取值棧
setParameters(action, stack, parameters);//為值棧設置參數
} finally {
//省略...
}
}
}
return invocation.invoke();//調用下一個攔截器
}

setParameters方法才是該攔截器的主要邏輯,現在進入該方法:

protected void setParameters(Object action, ValueStack stack, final Map<String, Object> parameters) {
ParameterNameAware parameterNameAware = (action instanceof ParameterNameAware)
? (ParameterNameAware) action : null;//判斷Action有無實現ParameterNameAware接口
Map<String, Object> params;
Map<String, Object> acceptableParameters;//合法參數集合
//判斷參數設置是否有序,ordered默認為false,即無序
if (ordered) {
params = new TreeMap<String, Object>(getOrderedComparator());//如果有序則要獲取比較器
acceptableParameters = new TreeMap<String, Object>(getOrderedComparator());
params.putAll(parameters);
} else {
params = new TreeMap<String, Object>(parameters);
acceptableParameters = new TreeMap<String, Object>();
}
//迭代請求參數
for (Map.Entry<String, Object> entry : params.entrySet()) {
String name = entry.getKey();
//判斷參數是否合法,如果Action實現了ParameterNameAware則acceptableName(name)返回true且parameterNameAware.acceptableParameterName(name)
//也返回true該參數才是合法的;如果Action沒有實現ParameterNameAware則參數是否合法由acceptableName(name)方法決定
boolean acceptableName = acceptableName(name) && (parameterNameAware == null || parameterNameAware.acceptableParameterName(name));
//如果參數合法
if (acceptableName) {
acceptableParameters.put(name, entry.getValue());//把合法參數添加到合法參數集合中
}
}
ValueStack newStack = valueStackFactory.createValueStack(stack);
//省略...
for (Map.Entry<String, Object> entry : acceptableParameters.entrySet()) {//迭代合法參數
String name = entry.getKey();//參數名
Object value = entry.getValue();//參數值
try {
newStack.setValue(name, value);//將該參數設置到ValueStack中
} catch (RuntimeException e) {
//省略...
}
}
//省略...
//看該方法的名稱是將合法參數添加到ActionContext中,但在該攔截器中,該方法為空實現,無任何代碼
//該方法被聲明為protected,即子類可以覆蓋該方法以改變行為
addParametersToContext(ActionContext.getContext(), acceptableParameters);
}

根據上面的注釋大家應該可以發現該setParameters方法邏輯還是很明確的,就是先判斷提交過來的參數是否合法,因為提交過來的參數會影響到值棧所以struts2要對提交過來的參數進行合法性檢查,以防止惡意用戶的攻擊,凡是請求參數中表達式中含有等號(=),逗號(,),#號(#)的都是非法表達式,現在就去看一下具體是如何判斷一個參數是否合法的。

上面注釋也講到了,如果Action實現了ParameterNameAware,即要判斷ParameterNameAware接口中聲明的acceptableParameterName(name)方法(邏輯由自己實現)也要判斷該攔截器的acceptableName(name)方法,我們這里假設Action沒有實現ParameterNameAware接口,參數是否合法由acceptableName(name)方法決定,下面是該方法源碼:

protected boolean acceptableName(String name) {
//調用isAccepted與isExcluded方法判斷
if (isAccepted(name) && !isExcluded(name)) {
return true;
}
return false;
}

isAccepted與isExcluded方法源碼:

protected boolean isAccepted(String paramName) {
if (!this.acceptParams.isEmpty()) {
for (Pattern pattern : acceptParams) {
Matcher matcher = pattern.matcher(paramName);
if (matcher.matches()) {
return true;
}
}
return false;
} else
return acceptedPattern.matcher(paramName).matches();
}
protected boolean isExcluded(String paramName) {
if (!this.excludeParams.isEmpty()) {
for (Pattern pattern : excludeParams) {
Matcher matcher = pattern.matcher(paramName);
if (matcher.matches()) {
return true;
}
}
}
return false;
}

上面說到了該攔截器配置了參數過濾,配置了一個名為excludeParams的參數,用于指定哪些參數要排除,即不合法,我們傳遞的時候是字符串在設置該字符串的時候該攔截器會對該字符串進行解析轉化成相應的Pattern對象以用于正則表達式校驗,而isAccepted與isExcluded方法中就是在用這些正則表達式進行檢驗,邏輯很簡單,就說這么多。

最終進行參數賦值是調用的ValueStack的setValue方法,該方法內部使用是OGNL表達式引擎進行賦值的,雖然內部非常復雜,但我們只需要知道OGNL表達式引擎在把請求參數設置到ValueStack中時,是從棧頂往棧底尋找有相應setter方法的對象,如果正在賦值的參數在ValueStack找到了一個對象有setter方法則把該參數的值賦給該對象,如果沒有找到則繼承往棧底尋找,直到找到為止,如果找到棧底還是沒有找到也就沒有賦值成功。

到此該攔截器就講解完畢了,最后調用invocation.invoke();調用下一個攔截器......

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 成人久久久精品乱码一区二区三区 | 久久免费视频8 | 久草在线高清 | 国产在线一区二区三区 | 成人免费午夜视频 | 韩国三级日本三级香港三级黄 | 国产高潮好爽好大受不了了 | 97色在线观看免费视频 | 国产精品久久久久久久久久大牛 | 国产毛片网 | 欧美福利视频一区二区三区 | 欧美雌雄另类xxxxx | 成年人在线免费播放视频 | 艹逼视频污 | 日韩欧美电影一区二区三区 | 国产69精品久久99不卡免费版 | 久草在线综合 | 欧美性猛交xxx乱大交3蜜桃 | 九九视频精品在线 | 成人免费毛片明星色大师 | 免费h片 | 美女黄色毛片免费看 | 2019中文字幕在线播放 | 欧美日韩精品一区二区三区不卡 | 黄视频免费观看 | 成人在线视频国产 | 黄色一级片免费在线观看 | 国产亚洲精品久久久久久久 | 精品国产一区在线 | 亚洲天堂成人在线 | 国产91精品一区二区麻豆亚洲 | 日日草夜夜草 | 91麻豆精品国产91久久久无需广告 | 欧美一区二区精品夜夜嗨 | 美女扒开腿让男生桶爽网站 | 国产品久久 | 黄色片快播| 小雪奶水翁胀公吸小说最新章节 | 本色视频aaaaaa一级网站 | 亚洲人成网在线观看 | 国产系列 视频二区 |