天天看點

Struts标簽的一些用法

關于<html:link>标簽在URI後面傳參數的問題

在struts标簽<html:link>的page屬性指定的URI後面傳遞參數可以有幾種方式:

1.若明确參數名和參數值則直接在URI後輸出,

如:<html:link page="/test.do?action=add">add</html:link>

2.對于參數值不确定的,paramName和paramProperty來輸出,用paramId屬性指定參數名。

對于paramName指定的對象應該存在于page、request、session、application其中之一。一般來說,是從Action類傳過來的,作為request的屬性之一(requst.setAttribute("name",object))。

如果paramName指定的對象是action的ActionForm,則無需使用request.setAttribute方法。

例:<html:link page="/test.do" paramId="userid" paramName="uid">uname</html:link>

若參數值是一個bean對象的屬性值(比如ActionForm,或者集合中存放的對象)則:

<html:link page="/test.do" paramId="userid" paramName="user" paramProperty="uid">uname</html:link>

3.若兩個參數,一個确定一個不确定,則是以上兩種方法的結合,即:

<html:link page="/test.do?action=modify" paramId="userid" paramName="uid">modify</html:link>

4.對于多個參數的問題,可以使用一個HashMap集合對象來存放所有的參數名及對應的參數值的方式,paramName屬性值指定為該HashMap集合對象即可。

舉例:

<%

//代碼理想的位置應該是在action中

//可以在jsp頁面測試

  java.util.HashMap pms = new java.util.HashMap();

  pms.put("code", "001002");

  pms.put("name", "tester");

  pms.put("alias", new String[]{"matin","jack"});

  request.setAttribute("params", pms);

%>

<html:link action="/test.do" name="params" >test</html:link>

編譯後的結果:<a href="/test.do?code=001002&name=tester&alias=matin&alias=jack" target="_blank" rel="external nofollow" >test</a>

這種方式雖然可以解決傳多參數的問題,但是實作起來也比較麻煩,特别是對記錄集中的資料逐條列出的時候

5.針對有的網友在<html:link>标簽中嵌入使用jsp腳本(scriptlet)的問題,

例如:

<html:link page="/test.do?code=<%=varible%>">add</html:link>,這種寫法是錯誤的,是無法編譯的。

有的網友認為在struts标簽内是不允許使用jsp腳本的,這種說法也不準确。如果前面的寫法改成:

<html:link page="<%="/test.do?code="+varible%>">add</html:link>,就可以被執行,但是要注意URL相對路徑的問題。

雖然在struts标簽中嵌入jsp腳本不是真正意義上的struts應用,但是有時在委曲求全的情況下也隻能如此了,除非使用自定義标簽。比如在form表單中可能需要根據具體資料讓某個字段是隻讀的,就可以用嵌入jsp腳本來實作:

<%

boolean rdonly=false;

if(2==2) rdonly=true;

%>

<html:text property="userid" readonly="<%=rdonly%>" />

6.另外一種比較變态的方法,既不是真正意義上的struts,也不符合xml規範。那就是在<a>标簽中用<bean:write>标簽輸出參數值。

如:<a href="test.do?uid=<bean:write name=" target="_blank" rel="external nofollow" user" property="userid"/>&name=<bean:write name="user" property="username"/>">test</a>

了解到這裡之後,感覺到一絲遺憾,因為如果隻有paramId,paramName,paramProperty這三個屬性的話,那麼對于html:link标簽來說,就永遠隻能自定義一個參數,如果需要定義多個參數,如http://serverip:portno/projectcontextname/html-link.do?a=3&b=5&y=9這樣的連結URL來說,就無能為力了

如果要定義多個參數,就需要手動拼URL,定義在page屬性裡面,這就失去了使用标簽的意義了。

在此情況下,懷着失望的心情,打開了Struts的源碼,開始檢視這個标簽的源碼,忽然發現,這個标簽完全是可以自定義多個參數的,關鍵就在name屬性上

首先來看一段如何自定義多個參數的代碼,如下:

=========================================================

<%

java.util.HashMap newValues = new java.util.HashMap();

newValues.put("floatProperty", new Float(444.0));

newValues.put("intProperty", new Integer(555));

newValues.put("stringArray", new String[]

{ "Value1", "Value2", "Value3" });

pageContext.setAttribute("newValues", newValues);

%>

<html:link page="/html-link.do" name="newValues">

Float, int, and stringArray via name (Map)

</html:link>

=========================================================

原來使用name屬性就可以将一個Map類型的變量放入request、session、application、page四種範圍的容器内,然後取個key值,填在name屬性裡就可以了

Struts将自動讀取這個Map類型對象的所有key和key所定義的對象,然後自動生成HTML代碼

好比上述的例子,将生成如下的HTML代碼:

<a href="http://serverip:portno/projectcontextname/html-link.do?stringArray=Value1&stringArray=Value2&stringArray=Value3&floatProperty=444.0&intProperty=555">

Float, int, and stringArray via name (Map)</a>

願望終于達到了,也充分證明了Struts的實力,但在這段實作中,查找name定義的對象這點在前面幾次的源碼剖析中已經很明确了(使用的是TagUtils.java中的lookup方法)

但得到這個對象後,Struts是如何讀出key值集合和key值對應的對象的呢?代碼在此:

=========================================================

// Add the required request parameters

boolean question = temp.indexOf(?) >= 0;

//這裡的params變量就是我們輸入的Map類型的對象

//就是這句代碼可以得到key值集合

Iterator keys = params.keySet().iterator();

while (keys.hasNext()) {

String key = (String) keys.next();

Object value = params.get(key);

if (value == null) {

if (!question) {

url.append(?);

question = true;

} else {

url.append(separator);

}

url.append(this.encodeURL(key));

url.append(=); // Interpret null as "no value"

} else if (value instanceof String) {

if (!question) {

url.append(?);

question = true;

} else {

url.append(separator);

}

url.append(this.encodeURL(key));

url.append(=);

url.append(this.encodeURL((String) value));

} else if (value instanceof String[]) {

String values[] = (String[]) value;

for (int i = 0; i < values.length; i++) {

if (!question) {

url.append(?);

question = true;

} else {

url.append(separator);

}

url.append(this.encodeURL(key));

url.append(=);

url.append(this.encodeURL(values[i]));

}

} else {

if (!question) {

url.append(?);

question = true;

} else {

url.append(separator);

}

url.append(this.encodeURL(key));

url.append(=);

url.append(this.encodeURL(value.toString()));

}

以上是看一個網友的Blog上得來的,自己正在被這個問題困擾,在那本<struts程式員查詢辭典>,關于<html:link>标簽的name屬性上是這麼說明的:指定其元素作為查詢字元串參數添加到目前連結的URL中的java.util.map對象的名字.如果還指定了property屬性,該屬性定義的對象中的某個字段将調用一個擷取值的方法,來傳回其元素作為查詢字元串參數被添加到目前連接配接的URL的java.util.map對象.

   偶最終的實作方法,無奈,有時間再研究吧!

<a href="../legalaid/legalAidSeAction.do?action=select7&id=<bean:write name=" target="_blank" rel="external nofollow" legalaid3" property="ID"/>&t19_n04=<bean:write name="legalaid3" property="t19_n04"/>">

     <bean:write name="legalaid3" property="t19_c02"/>

</a>