亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

OGNL的學(xué)習(xí)指南

系統(tǒng) 2088 0

OGNL —— 完美的催化劑

為了解決數(shù)據(jù)從View層傳遞到Controller層時(shí)的不匹配性,Struts2采納了XWork的OGNL方案。并且在OGNL的基礎(chǔ)上,構(gòu)建了OGNLValueStack的機(jī)制,從而比較完美的解決了數(shù)據(jù)流轉(zhuǎn)中的不匹配性。

OGNL(Object Graph Navigation Language),是一種表達(dá)式語(yǔ)言。使用這種表達(dá)式語(yǔ)言,你可以通過(guò)某種表達(dá)式語(yǔ)法,存取Java對(duì)象樹中的任意屬性、調(diào)用Java對(duì)象樹的方法、同時(shí)能夠自動(dòng)實(shí)現(xiàn)必要的類型轉(zhuǎn)化。如果我們把表達(dá)式看做是一個(gè)帶有語(yǔ)義的字符串,那么OGNL無(wú)疑成為了這個(gè)語(yǔ)義字符串與Java對(duì)象之間溝通的橋梁。

如何使用OGNL

讓我們先研究一下OGNL的API,他來(lái)自于Ognl的靜態(tài)方法:

Java代碼 復(fù)制代碼
  1. ??
  2. /** ?
  3. ?*?Evaluates?the?given?OGNL?expression?tree?to?extract?a?value?from?the?given?root ?
  4. ?*?object.?The?default?context?is?set?for?the?given?context?and?root?via ?
  5. ?*?<CODE>addDefaultContext()</CODE>. ?
  6. ?* ?
  7. ?*?@param?tree?the?OGNL?expression?tree?to?evaluate,?as?returned?by?parseExpression() ?
  8. ?*?@param?context?the?naming?context?for?the?evaluation ?
  9. ?*?@param?root?the?root?object?for?the?OGNL?expression ?
  10. ?*?@return?the?result?of?evaluating?the?expression ?
  11. ?*?@throws?MethodFailedException?if?the?expression?called?a?method?which?failed ?
  12. ?*?@throws?NoSuchPropertyException?if?the?expression?referred?to?a?nonexistent?property ?
  13. ?*?@throws?InappropriateExpressionException?if?the?expression?can't?be?used?in?this?context ?
  14. ?*?@throws?OgnlException?if?there?is?a?pathological?environmental?problem ?
  15. ?*/ ??
  16. public ? static ?Object?getValue(?Object?tree,?Map?context,?Object?root?)? throws ?OgnlException; ??
  17. ??
  18. /** ?
  19. ?*?Evaluates?the?given?OGNL?expression?tree?to?insert?a?value?into?the?object?graph ?
  20. ?*?rooted?at?the?given?root?object.??The?default?context?is?set?for?the?given ?
  21. ?*?context?and?root?via?<CODE>addDefaultContext()</CODE>. ?
  22. ?* ?
  23. ?*?@param?tree?the?OGNL?expression?tree?to?evaluate,?as?returned?by?parseExpression() ?
  24. ?*?@param?context?the?naming?context?for?the?evaluation ?
  25. ?*?@param?root?the?root?object?for?the?OGNL?expression ?
  26. ?*?@param?value?the?value?to?insert?into?the?object?graph ?
  27. ?*?@throws?MethodFailedException?if?the?expression?called?a?method?which?failed ?
  28. ?*?@throws?NoSuchPropertyException?if?the?expression?referred?to?a?nonexistent?property ?
  29. ?*?@throws?InappropriateExpressionException?if?the?expression?can't?be?used?in?this?context ?
  30. ?*?@throws?OgnlException?if?there?is?a?pathological?environmental?problem ?
  31. ?*/ ??
  32. public ? static ? void ?setValue(?Object?tree,?Map?context,?Object?root,?Object?value?)? throws ?OgnlException??
    /**
 * Evaluates the given OGNL expression tree to extract a value from the given root
 * object. The default context is set for the given context and root via
 * <CODE>addDefaultContext()</CODE>.
 *
 * @param tree the OGNL expression tree to evaluate, as returned by parseExpression()
 * @param context the naming context for the evaluation
 * @param root the root object for the OGNL expression
 * @return the result of evaluating the expression
 * @throws MethodFailedException if the expression called a method which failed
 * @throws NoSuchPropertyException if the expression referred to a nonexistent property
 * @throws InappropriateExpressionException if the expression can't be used in this context
 * @throws OgnlException if there is a pathological environmental problem
 */
public static Object getValue( Object tree, Map context, Object root ) throws OgnlException;

/**
 * Evaluates the given OGNL expression tree to insert a value into the object graph
 * rooted at the given root object.  The default context is set for the given
 * context and root via <CODE>addDefaultContext()</CODE>.
 *
 * @param tree the OGNL expression tree to evaluate, as returned by parseExpression()
 * @param context the naming context for the evaluation
 * @param root the root object for the OGNL expression
 * @param value the value to insert into the object graph
 * @throws MethodFailedException if the expression called a method which failed
 * @throws NoSuchPropertyException if the expression referred to a nonexistent property
 * @throws InappropriateExpressionException if the expression can't be used in this context
 * @throws OgnlException if there is a pathological environmental problem
 */
public static void setValue( Object tree, Map context, Object root, Object value ) throws OgnlException


  



我們可以看到,OGNL的API其實(shí)相當(dāng)簡(jiǎn)單,你可以通過(guò)傳遞三個(gè)參數(shù)來(lái)實(shí)現(xiàn)OGNL的一切操作。而這三個(gè)參數(shù),被我稱為OGNL的三要素。

那么運(yùn)用這個(gè)API,我們能干點(diǎn)什么呢?跑個(gè)測(cè)試看看結(jié)果:

Java代碼 復(fù)制代碼
  1. ??
  2. /** ?
  3. ?*?@author?Downpour ?
  4. ?*/ ??
  5. public ? class ?User?{ ??
  6. ???? ??
  7. ???? private ?Integer?id; ??
  8. ???? ??
  9. ???? private ?String?name; ??
  10. ???? ??
  11. ???? private ?Department?department?=? new ?Department(); ??
  12. ???? ??
  13. ???? public ?User()?{ ??
  14. ???????? ??
  15. ????} ??
  16. ???????? ??
  17. ???????? //?setter?and?getters ??
  18. } ??
  19. ??
  20. //========================================================================= ??
  21. ??
  22. /** ?
  23. ?*?@author?Downpour ?
  24. ?*/ ??
  25. public ? class ?Department?{ ??
  26. ???? ??
  27. ???? private ?Integer?id; ??
  28. ???? ??
  29. ???? private ?String?name; ??
  30. ???? ??
  31. ???? public ?Department()?{ ??
  32. ???????? ??
  33. ????} ??
  34. ???????? ??
  35. ???????? //?setter?and?getters ??
  36. } ??
  37. ??
  38. //========================================================================= ??
  39. ??
  40. /** ?
  41. ?*?@author?Downpour ?
  42. ?*/ ??
  43. public ? class ?OGNLTestCase? extends ?TestCase?{ ??
  44. ???? ??
  45. ???? /** ?
  46. ?????*? ?
  47. ?????*?@throws?Exception ?
  48. ?????*/ ??
  49. ???? @SuppressWarnings ( "unchecked" ) ??
  50. ???? @Test ??
  51. ???? public ? void ?testGetValue()? throws ?Exception?{ ??
  52. ???????? ??
  53. ???????? //?Create?root?object ??
  54. ????????User?user?=? new ?User(); ??
  55. ????????user.setId( 1 ); ??
  56. ????????user.setName( "downpour" ); ??
  57. ??
  58. ???????? //?Create?context ??
  59. ????????Map?context?=? new ?HashMap(); ??
  60. ????????context.put( "introduction" , "My?name?is?" ); ??
  61. ???????? ??
  62. ???????? //?Test?to?directly?get?value?from?root?object,?with?no?context ??
  63. ????????Object?name?=?Ognl.getValue(Ognl.parseExpression( "name" ),?user); ??
  64. ????????assertEquals( "downpour" ,name); ??
  65. ???????? ??
  66. ???????? //?Test?to?get?value(parameter)?from?context ??
  67. ????????Object?contextValue?=?Ognl.getValue(Ognl.parseExpression( "#introduction" ),?context,?user); ??
  68. ????????assertEquals( "My?name?is?" ,?contextValue); ??
  69. ???????? ??
  70. ???????? //?Test?to?get?value?and?parameter?from?root?object?and?context ??
  71. ????????Object?hello?=?Ognl.getValue(Ognl.parseExpression( "#introduction?+?name" ),?context,?user); ??
  72. ????????assertEquals( "My?name?is?downpour" ,hello); ??
  73. ???????????????????? ??
  74. ????} ??
  75. ??
  76. ???? /** ?
  77. ?????*? ?
  78. ?????*?@throws?Exception ?
  79. ?????*/ ??
  80. ???? @SuppressWarnings ( "unchecked" ) ??
  81. ???? @Test ??
  82. ???? public ? void ?testSetValue()? throws ?Exception?{ ??
  83. ???????? ??
  84. ???????? //?Create?root?object ??
  85. ????????User?user?=? new ?User(); ??
  86. ????????user.setId( 1 ); ??
  87. ????????user.setName( "downpour" ); ??
  88. ???????? ??
  89. ???????????????? //?Set?value?according?to?the?expression ??
  90. ????????Ognl.setValue( "department.name" ,?user,? "dev" ); ??
  91. ????????assertEquals( "dev" ,?user.getDepartment().getName()); ??
  92. ???????? ??
  93. ????} ??
  94. ???? ??
  95. ??
  96. }??
    /**
 * @author Downpour
 */
public class User {
	
	private Integer id;
	
	private String name;
	
	private Department department = new Department();
	
	public User() {
		
	}
        
        // setter and getters
}

//=========================================================================

/**
 * @author Downpour
 */
public class Department {
	
	private Integer id;
	
	private String name;
	
	public Department() {
		
	}
        
        // setter and getters
}

//=========================================================================

/**
 * @author Downpour
 */
public class OGNLTestCase extends TestCase {
	
	/**
	 * 
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	@Test
	public void testGetValue() throws Exception {
		
		// Create root object
		User user = new User();
		user.setId(1);
		user.setName("downpour");

		// Create context
		Map context = new HashMap();
		context.put("introduction","My name is ");
		
		// Test to directly get value from root object, with no context
		Object name = Ognl.getValue(Ognl.parseExpression("name"), user);
		assertEquals("downpour",name);
		
		// Test to get value(parameter) from context
		Object contextValue = Ognl.getValue(Ognl.parseExpression("#introduction"), context, user);
		assertEquals("My name is ", contextValue);
		
		// Test to get value and parameter from root object and context
		Object hello = Ognl.getValue(Ognl.parseExpression("#introduction + name"), context, user);
		assertEquals("My name is downpour",hello);
					
	}

	/**
	 * 
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	@Test
	public void testSetValue() throws Exception {
		
		// Create root object
		User user = new User();
		user.setId(1);
		user.setName("downpour");
		
                // Set value according to the expression
		Ognl.setValue("department.name", user, "dev");
		assertEquals("dev", user.getDepartment().getName());
		
	}
	

}


  



我們可以看到,簡(jiǎn)單的API,就已經(jīng)能夠完成對(duì)各種對(duì)象樹的讀取和設(shè)值工作了。這也體現(xiàn)出OGNL的學(xué)習(xí)成本非常低。

在上面的測(cè)試用例中,需要特別強(qiáng)調(diào)進(jìn)行區(qū)分的,是在針對(duì)不同內(nèi)容進(jìn)行取值或者設(shè)值時(shí),OGNL表達(dá)式的不同。

Struts2 Reference 寫道
The framework uses a standard naming context to evaluate OGNL expressions. The top level object dealing with OGNL is a Map (usually referred as a context map or context). OGNL has a notion of there being a root (or default) object within the context. In expression, the properties of the root object can be referenced without any special "marker" notion. References to other objects are marked with a pound sign (#).



上面這段內(nèi)容摘自Struts2的Reference,我把這段話總結(jié)為以下2條規(guī)則:

A) 針對(duì)根對(duì)象(Root Object)的操作,表達(dá)式是自根對(duì)象到被訪問(wèn)對(duì)象的某個(gè)鏈?zhǔn)讲僮鞯淖址硎尽?
B) 針對(duì)上下文環(huán)境(Context)的操作,表達(dá)式是自上下文環(huán)境(Context)到被訪問(wèn)對(duì)象的某個(gè)鏈?zhǔn)讲僮鞯淖址硎?,但是必須在這個(gè)字符串的前面加上#符號(hào),以表示與訪問(wèn)根對(duì)象的區(qū)別。


上面的這點(diǎn)區(qū)別咋看起來(lái)非常容易理解,不過(guò)一旦放到特定的環(huán)境中,就會(huì)顯示出其重要性,它可以解釋很多Struts2在頁(yè)面展示上取值的各種復(fù)雜的表達(dá)式的現(xiàn)象。這一點(diǎn)在下一篇文章中會(huì)進(jìn)行具體的分析。

OGNL三要素

我把傳入OGNL的API的三個(gè)參數(shù),稱之為OGNL的三要素。OGNL的操作實(shí)際上就是圍繞著這三個(gè)參數(shù)而進(jìn)行的。

1. 表達(dá)式(Expression)

表達(dá)式是整個(gè)OGNL的核心,所有的OGNL操作都是針對(duì)表達(dá)式的解析后進(jìn)行的。表達(dá)式會(huì)規(guī)定此次OGNL操作到底要 干什么 。

我們可以看到,在上面的測(cè)試中,name、department.name等都是表達(dá)式,表示取name或者department中的name的值。OGNL支持很多類型的表達(dá)式,之后我們會(huì)看到更多。

2. 根對(duì)象(Root Object)

根對(duì)象可以理解為OGNL的 操作對(duì)象 。在表達(dá)式規(guī)定了“干什么”以后,你還需要指定到底 “對(duì)誰(shuí)干” 。

在上面的測(cè)試代碼中,user就是根對(duì)象。這就意味著,我們需要對(duì)user這個(gè)對(duì)象去取name這個(gè)屬性的值(對(duì)user這個(gè)對(duì)象去設(shè)置其中的department中的name屬性值)。

3. 上下文環(huán)境(Context)

有了表達(dá)式和根對(duì)象,我們實(shí)際上已經(jīng)可以使用OGNL的基本功能。例如,根據(jù)表達(dá)式對(duì)根對(duì)象進(jìn)行取值或者設(shè)值工作。

不過(guò)實(shí)際上,在OGNL的內(nèi)部,所有的操作都會(huì)在一個(gè)特定的環(huán)境中運(yùn)行,這個(gè)環(huán)境就是OGNL的上下文環(huán)境(Context)。說(shuō)得再明白一些,就是這個(gè)上下文環(huán)境(Context),將規(guī)定OGNL的操作 “在哪里干” 。

OGNL的上下文環(huán)境是一個(gè)Map結(jié)構(gòu),稱之為OgnlContext。上面我們提到的根對(duì)象(Root Object),事實(shí)上也會(huì)被加入到上下文環(huán)境中去,并且這將作為一個(gè)特殊的變量進(jìn)行處理,具體就表現(xiàn)為針對(duì)根對(duì)象(Root Object)的存取操作的表達(dá)式是不需要增加#符號(hào)進(jìn)行區(qū)分的。

OgnlContext不僅提供了OGNL的運(yùn)行環(huán)境。在這其中,我們還能設(shè)置一些自定義的parameter到Context中,以便我們?cè)谶M(jìn)行OGNL操作的時(shí)候能夠方便的使用這些parameter。不過(guò)正如我們上面反復(fù)強(qiáng)調(diào)的,我們?cè)谠L問(wèn)這些parameter時(shí),需要使用#作為前綴才能進(jìn)行。

OGNL與模板

我們?cè)趪L試了OGNL的基本操作并了解了OGNL的三要素之后,或許很容易把OGNL的操作與模板聯(lián)系起來(lái)進(jìn)行比較。在很多方面,他們也的確有著相似之處。

對(duì)于模板,會(huì)有一些普通的輸出元素,也有一些模板語(yǔ)言特殊的符號(hào)構(gòu)成的元素,這些元素一旦與具體的Java對(duì)象融合起來(lái),就會(huì)得到我們需要的輸出結(jié)果。

而OGNL看起來(lái)也是非常的類似,OGNL中的表達(dá)式就雷同于模板語(yǔ)言的特殊符號(hào),目的是針對(duì)某些Java對(duì)象進(jìn)行存取。而OGNL與模板都將數(shù)據(jù)與展現(xiàn)分開,將數(shù)據(jù)放到某個(gè)特定的地方,具體來(lái)說(shuō),就是Java對(duì)象。只是OGNL與模板的語(yǔ)法結(jié)構(gòu)不完全相同而已。

深入淺出OGNL

在了解了OGNL的API和基本操作以后,我們來(lái)深入到OGNL的內(nèi)部來(lái)看看,挖掘一些更加深入的知識(shí)。

OGNL表達(dá)式

OGNL支持各種紛繁復(fù)雜的表達(dá)式。但是最最基本的表達(dá)式的原型,是將對(duì)象的引用值用點(diǎn)串聯(lián)起來(lái),從左到右,每一次表達(dá)式計(jì)算返回的結(jié)果成為當(dāng)前對(duì)象,后面部分接著在當(dāng)前對(duì)象上進(jìn)行計(jì)算,一直到全部表達(dá)式計(jì)算完成,返回最后得到的對(duì)象。OGNL則針對(duì)這條基本原則進(jìn)行不斷的擴(kuò)充,從而使之支持對(duì)象樹、數(shù)組、容器的訪問(wèn),甚至是類似SQL中的投影選擇等操作。

接下來(lái)我們就來(lái)看看一些常用的OGNL表達(dá)式:

1. 基本對(duì)象樹的訪問(wèn)

對(duì)象樹的訪問(wèn)就是通過(guò)使用點(diǎn)號(hào)將對(duì)象的引用串聯(lián)起來(lái)進(jìn)行。

例如:name,department.name,user.department.factory.manager.name

2. 對(duì)容器變量的訪問(wèn)

對(duì)容器變量的訪問(wèn),通過(guò)#符號(hào)加上表達(dá)式進(jìn)行。

例如:#name,#department.name,#user.department.factory.manager.name

3. 使用操作符號(hào)

OGNL表達(dá)式中能使用的操作符基本跟Java里的操作符一樣,除了能使用 +, -, *, /, ++, --, ==, !=, = 等操作符之外,還能使用 mod, in, not in等。

4. 容器、數(shù)組、對(duì)象

OGNL支持對(duì)數(shù)組和ArrayList等容器的順序訪問(wèn):

例如:group.users[0]

同時(shí),OGNL支持對(duì)Map的按鍵值查找:

例如:#session['mySessionPropKey']

不僅如此,OGNL還支持容器的構(gòu)造的表達(dá)式:

例如:{"green", "red", "blue"}構(gòu)造一個(gè)List,#{"key1" : "value1", "key2" : "value2", "key3" : "value3"}構(gòu)造一個(gè)Map

你也可以通過(guò)任意類對(duì)象的構(gòu)造函數(shù)進(jìn)行對(duì)象新建:

例如:new java.net.URL("http://localhost/")

5. 對(duì)靜態(tài)方法或變量的訪問(wèn)

要引用類的靜態(tài)方法和字段,他們的表達(dá)方式是一樣的@class@member或者@class@method(args):

例如:@com.javaeye.core.Resource@ENABLE,@com.javaeye.core.Resource@getAllResources

6. 方法調(diào)用

直接通過(guò)類似Java的方法調(diào)用方式進(jìn)行,你甚至可以傳遞參數(shù):

例如:user.getName(),group.users.size(),group.containsUser(#requestUser)

7. 投影和選擇



OGNL支持類似數(shù)據(jù)庫(kù)中的投影(projection) 和選擇(selection)。

投影就是選出集合中每個(gè)元素的相同屬性組成新的集合,類似于關(guān)系數(shù)據(jù)庫(kù)的字段操作。投影操作語(yǔ)法為 collection.{XXX},其中XXX 是這個(gè)集合中每個(gè)元素的公共屬性。

例如:group.userList.{username}將獲得某個(gè)group中的所有user的name的列表。

選擇就是過(guò)濾滿足selection 條件的集合元素,類似于關(guān)系數(shù)據(jù)庫(kù)的紀(jì)錄操作。選擇操作的語(yǔ)法為:collection.{X YYY},其中X 是一個(gè)選擇操作符,后面則是選擇用的邏輯表達(dá)式。而選擇操作符有三種:
? 選擇滿足條件的所有元素
^ 選擇滿足條件的第一個(gè)元素
$ 選擇滿足條件的最后一個(gè)元素

例如:group.userList.{? #this.name != null}將獲得某個(gè)group中user的name不為空的user的列表。

上述的所有的表達(dá)式,只是對(duì)OGNL所有表達(dá)式的大概的一個(gè)概括,除此之外,OGNL還有更多的表達(dá)式,例如lamba表達(dá)式等等。最具體的表達(dá)式的文檔,大家可以參考OGNL自帶的文檔:

http://www.ognl.org/2.6.9/Documentation/html/LanguageGuide/apa.html

在撰寫時(shí),我也參考了potain同學(xué)的XWork教程以及一些網(wǎng)絡(luò)上的一些文章,特此列出:

http://www.lifevv.com/java/doc/20071018173750030.html

http://blog.csdn.net/ice_fire2008/archive/2008/05/12/2438817.aspx

OGNLContext

OGNLContext就是OGNL的運(yùn)行上下文環(huán)境。OGNLContext其實(shí)是一個(gè)Map結(jié)構(gòu),如果查看一下它的源碼,就會(huì)發(fā)現(xiàn),它其實(shí)實(shí)現(xiàn)了java.utils.Map的接口。當(dāng)你在調(diào)用OGNL的取值或者設(shè)值的方法時(shí),你可能會(huì)自己定義一個(gè)Context,并且將它傳遞給方法。事實(shí)上,你所傳遞進(jìn)去的這個(gè)Context,會(huì)在OGNL內(nèi)部被轉(zhuǎn)化成OGNLContext,而你傳遞進(jìn)去的所有的鍵值對(duì),也會(huì)被OGNLContext接管維護(hù),這里有點(diǎn)類似一個(gè)裝飾器,向你屏蔽了一些其內(nèi)部的實(shí)現(xiàn)機(jī)理。

在OGNLContext的內(nèi)部維護(hù)的東西很多,其中,我挑選2個(gè)比較重要的提一下。一個(gè)是你在調(diào)用方法時(shí)傳入的Context,它會(huì)被維護(hù)在OGNL內(nèi)部,并且作為存取變量的基礎(chǔ)依據(jù)。另外一個(gè),是在Context內(nèi)部維護(hù)了一個(gè)key為root的值,它將規(guī)定在OGNLContext進(jìn)行計(jì)算時(shí),哪個(gè)元素被指定為根對(duì)象。其在進(jìn)行存取時(shí),將會(huì)被特殊對(duì)待。

this指針

我們知道,OGNL表達(dá)式是以點(diǎn)進(jìn)行串聯(lián)的一個(gè)字符串鏈?zhǔn)奖磉_(dá)式。而這個(gè)表達(dá)式在進(jìn)行計(jì)算的時(shí)候,從左到右,每一次表達(dá)式計(jì)算返回的結(jié)果成為當(dāng)前對(duì)象,并繼續(xù)進(jìn)行計(jì)算,直到得到計(jì)算結(jié)果。每次計(jì)算的中間對(duì)象都會(huì)放在一個(gè)叫做this的變量里面這個(gè)this變量就稱之為this指針。

例如:group.userList.size().(#this+1).toString()

在這個(gè)例子中,#this其實(shí)就是group.userList.size()的計(jì)算結(jié)構(gòu)。

使用this指針,我們就可以在OGNL表達(dá)式中進(jìn)行一些簡(jiǎn)單的計(jì)算,從而完成我們的計(jì)算邏輯,而this指針在lamba表達(dá)式的引用中尤為廣泛,有興趣的讀者可以深入研究OGNL自帶的文檔中l(wèi)amba表達(dá)式的章節(jié)。

默認(rèn)行為和類型轉(zhuǎn)化

在我們所講述的所有的OGNL的操作中,實(shí)際上,全部都忽略了OGNL內(nèi)部幫助你完成的很多默認(rèn)行為和類型轉(zhuǎn)化方面的工作。

我們來(lái)看一下OGNL在進(jìn)行操作初始化時(shí)候的一個(gè)函數(shù)簽名:

Java代碼 復(fù)制代碼
  1. ??
  2. /** ?
  3. ?*?Appends?the?standard?naming?context?for?evaluating?an?OGNL?expression ?
  4. ?*?into?the?context?given?so?that?cached?maps?can?be?used?as?a?context. ?
  5. ?* ?
  6. ?*?@param?root?the?root?of?the?object?graph ?
  7. ?*?@param?context?the?context?to?which?OGNL?context?will?be?added. ?
  8. ?*?@return?Context?Map?with?the?keys?<CODE>root</CODE>?and?<CODE>context</CODE> ?
  9. ?*?????????set?appropriately ?
  10. ?*/ ??
  11. public ? static ?Map?addDefaultContext(?Object?root,?ClassResolver?classResolver,?TypeConverter?converter,?MemberAccess?memberAccess,?Map?context?);??
    /**
 * Appends the standard naming context for evaluating an OGNL expression
 * into the context given so that cached maps can be used as a context.
 *
 * @param root the root of the object graph
 * @param context the context to which OGNL context will be added.
 * @return Context Map with the keys <CODE>root</CODE> and <CODE>context</CODE>
 *         set appropriately
 */
public static Map addDefaultContext( Object root, ClassResolver classResolver, TypeConverter converter, MemberAccess memberAccess, Map context );


  



可以看到,在初始化時(shí),OGNL還需要額外初始化一個(gè)類型轉(zhuǎn)化的接口和一些其他的信息。只不過(guò)這些默認(rèn)行為,由OGNL的內(nèi)部屏蔽了。

一旦需要自己定義針對(duì)某個(gè)特定類型的類型轉(zhuǎn)化方式,你就需要實(shí)現(xiàn)TypeConverter接口,并且在OGNL中進(jìn)行注冊(cè)。

同時(shí),如果需要對(duì)OGNL的許多默認(rèn)行為做出改變,則需要通過(guò)設(shè)置OGNL的全局環(huán)境變量進(jìn)行。

上述的這些內(nèi)容,有些會(huì)在后面的章節(jié)涉及,有興趣的讀者,也可以參閱OGNL的源碼和OGNL的文檔尋求幫助。

OGNL的學(xué)習(xí)指南


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦?。?!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 日本波多野结衣在线 | 亚洲黄色高清 | 精品国产97在线观看 | 乱色美www女麻豆 | 日本人成年视频在线观看 | 香蕉久久网站 | 国产一级免费视频 | 精品久久久久久午夜 | 伊人色婷婷 | 97国产在线公开免费观看 | 中文字幕一视频97色伦 | 夭天干天天做天天免费看 | 91色蝌蚪| 久久久久久久久a免费 | 一本一道波多野结衣一区二区 | 亚洲欧美日韩一区成人 | 久久综合香蕉 | 精品久久天干天天天按摩 | 久久综合久久美利坚合众国 | 亚洲一区免费在线观看 | 国产成人久久综合二区 | 一区二区三区精品国产欧美 | 91青娱国产| 久久精品女人毛片国产 | 免费毛片观看 | 亚洲午夜片子大全精品 | a级免费网站 | 免费区一级欧美毛片 | 国产亚洲精品久久精品6 | 亚洲第一区第二区 | 尤物视频在线免费观看 | 日本不卡视频在线 | 亚洲一区 在线播放 | 中中文字幕亚州无线码 | 噜噜狠狠 | 国产欧美一区二区三区免费看 | 99人中文字幕亚洲区 | 国内精品伊人久久久久7777人 | 日本高清中文字幕一区二区三区a | 天天摸天天碰色综合网 | 亚洲成人在线免费视频 |