1 標籤與屬性範圍
在Struts 2.x裏面,每一個JSP頁面一定要與Action緊密聯繫在一起,尤其是在Action進行了服務器端跳轉之後,也同樣可以直接利用標籤訪問這個類中的私有屬性。
範例:定義一個新的Action
package org.lks.action;
import org.lks.vo.Department;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
public class DepartmentAction extends ActionSupport {
private Department department = new Department();
public Department getDepartment() {
return department;
}
@Override
public String execute() throws Exception {
this.department.setDid(1001L);
this.department.setDname("設計部");
this.department.setDlocation("米蘭");
return "department.show";
}
}
<action name="DepartmentAction" class="org.lks.action.DepartmentAction">
<result name="department.show">department_show.jsp</result>
</action>
此時直接在Action裏面直接設置了一個department的VO類對象,隨後定義了對象的內容,並且讓其跳轉到了一個指定的頁面,但是這個頁面要使用標籤輸出內容。
範例:定義department_show.jsp頁面
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html>
<head>
<base href="<%=basePath%>">
<title>Struts 2.x</title>
</head>
<body>
<h1><s:property value="department.did"/></h1>
<h1><s:property value="department.dname"/></h1>
<h1><s:property value="department.dlocation"/></h1>
</body>
</html>
這個時候所有的標籤不需要做任何直接性的處理就可以找到跳轉過來的Action本身所具備的內容。
但是在編寫代碼的過程之中,Struts 2.x這種將JSP與Action緊密連接的形式我們並不會習慣,因爲大部分人都習慣於利用request屬性傳遞操作。
範例:利用request屬性傳遞
@Override
public String execute() throws Exception {
this.department.setDid(1001L);
this.department.setDname("設計部");
this.department.setDlocation("米蘭");
ServletActionContext.getRequest().setAttribute("department", department);
return "department.show";
}
此時的標籤無法找到屬性範圍中的內容,那麼如果要想在Struts 2.x的標籤裏面訪問屬性範圍中的內容則在訪問前請加上#範圍名稱
,例如#request
表示request屬性範圍。
範例:修改標籤
<body>
<h1><s:property value="#request.department.did"/></h1>
<h1><s:property value="#request.department.dname"/></h1>
<h1><s:property value="#request.department.dlocation"/></h1>
</body>
如果要想使用Struts的標籤就必須使用OGNL的表達式語言完成。
2 非UI標籤
本部分的標籤指的是於表單無關(表單在HTML裏面就稱爲UI),下面看幾個有意思的標籤:
1、格式化日期顯示
如果要想格式化日期的顯示則使用<s:date>
標籤完成。
<h1><s:date name="#hiredate" format="yyyy-MM-dd"/></h1>
以上的標籤是直接訪問了在Action中的屬性內容,如果說現在要是訪問屬性範圍中的內容請使用#request
作爲標記。
ServletActionContext.getRequest().setAttribute("birthday", new java.util.Date());
<h1><s:date name="#request.birthday" format="yyyy-MM-dd"/></h1>
2、文本輸出,在一個項目裏面一定會存在有資源文件,例如,有了一個Messages.properties文件,那麼這個文件的內容除了可以使用Action讀取之外,也可以使用標籤完成讀取。
<h1><s:i18n name="Messages">
<s:text name="info">
<s:param>Hello</s:param>
</s:text>
</s:i18n> </h1>
大部分情況下不需要如此操作,因爲大部分內容都是通過Action讀取的,如果你日後遇見有國際化程序的時候,那麼請一定要這樣讀取。
3、在整個頁面之中,實際上最爲重要的標籤有兩個:判斷是否有內容,以及迭代輸出。;
範例:生成一個List集合
Department department = null;
for(int i=0; i < 10; i++){
department = new Department();
department.setDid(100L + i);
department.setDname("部門" + i);
department.setDlocation("地點" + i);
this.departments.add(department);
}
此時的程序之中,List集合是作爲了DepartmentAction的屬性,所以標籤可以直接操作。
範例:迭代輸出
<s:if test="departments!=null">
<s:iterator value="departments" var="dept" >
<h2>
<s:property value="did"/>?
<s:property value="dname"/>?
<s:property value="dlocation"/>
</h2>
</s:iterator>
</s:if>
<s:if test="departments!=null">
<s:iterator value="departments" var="dept" >
<h2>
${dept.did }?
${dept.dname }?
${dept.dlocation }?
</h2>
</s:iterator>
</s:if>
如果說現在要進行屬性傳遞的操作,那麼必須也加上#
符號。
ServletActionContext.getRequest().setAttribute("departments", departments);
<s:if test="#request.departments!=null">
<s:iterator value="#request.departments" var="dept" >
<h2>
${dept.did }?
${dept.dname }
${dept.dlocation }?
</h2>
</s:iterator>
</s:if>
在所有的標籤之中,判斷和輸出是我們最需要掌握的標籤。
3 UI標籤
在Struts 2.x裏面本意是希望方便用戶的開發,所以在許多的標籤上都使用了操作模板,但是在實際的佈局中這些模板如果出現會破壞佈局要求。
範例:觀察表單問題
<body>
<s:form>
<s:textfield name="department.did" value="1001" />
<s:textfield name="department.dname" value="soft" />
<s:textfield name="department.dlocation" value="NewYork" />
<s:submit value="submit" />
<s:reset value="reset" />
</s:form>
</body>
<body data-genuitec-lp-enabled="false" data-genuitec-file-id="wc1-5"
data-genuitec-path="/MyStruts2Project/WebRoot/department_insert.jsp">
<form id="DepartmentAction" name="DepartmentAction"
action="/MyStruts2Project/DepartmentAction.action" method="post">
<table class="wwFormTable">
<tr>
<td class="tdLabel"></td>
<td><input type="text" name="department.did" value="1001"
id="DepartmentAction_department_did" /></td>
</tr>
<tr>
<td class="tdLabel"></td>
<td><input type="text" name="department.dname" value="soft"
id="DepartmentAction_department_dname" /></td>
</tr>
<tr>
<td class="tdLabel"></td>
<td><input type="text" name="department.dlocation"
value="NewYork" id="DepartmentAction_department_dlocation" /></td>
</tr>
<tr>
<td colspan="2"><div align="right">
<input type="submit" id="DepartmentAction_0" value="submit" />
</div></td>
</tr>
<tr>
<td colspan="2"><div align="right">
<input type="reset" value="reset" />
</div></td>
</tr>
</table>
</form>
</body>
所以這個時候如果使用了UI標籤就必須承受這些生成代碼所帶來的問題。但是爲了解決這種佈局所帶來的混亂,可以取消掉使用的頁面模板。
範例:取消模板
<body>
<s:form theme="simple">
<s:textfield name="department.did" value="1001" theme="simple" />
<s:textfield name="department.dname" value="soft" theme="simple" />
<s:textfield name="department.dlocation" value="NewYork" theme="simple" />
<s:submit value="submit" theme="simple" />
<s:reset value="reset" theme="simple" />
</s:form>
</body>
此時雖然取消了佈局代碼對頁面的影響,但是對於前端工程師來講依然無法知道此類代碼。這些是標籤,在直白的界面下無法顯示,也就是說如果有美工要進行修飾,那麼美工還必須自己搭建好服務器,設置好Struts,完全不靠譜。
如果公正的來講,UI標籤在一些組件的生成上還是挺方便的,例如,現在要傳遞一組部門信息,希望可以生成下拉列表框。
範例:在Action保存一組部門信息
List<Department> departments = new ArrayList<Department>();
Department dept = null;
for(int i=0; i < 10; i++){
dept = new Department();
dept.setDid(100L + i);
dept.setDname("部門" + i);
dept.setDlocation("地點" + i);
departments.add(dept);
}
ServletActionContext.getRequest().setAttribute("departments", departments);
如果此時頁面中要想輸出下拉列表框有兩種選擇,一種是利用循環採用迭代的方式輸出每一個下拉的列表項,,另外一種是使用Struts 2.x標籤生成。
範例:利用標籤生成
<s:select list="#request.departments" listKey="did" listValue="dname" theme="simple"/>
除了生成下拉列表框之外也可以生成複選框。
範例:利用標籤生成複選框
<s:checkboxlist list="#request.departments" listKey="did" listValue="dname" name="dno" id="dno" theme="simple"/>
如果要想接收復選框得內容,可以在Action裏面定義數組。
範例:接收復選框數據
private Integer[] dno;
public void setDno(Integer[] dno) {
this.dno = dno;
}
public Integer[] getDno() {
return dno;
}
此時發現不管是單值還是一個數組,都可以自動實現轉型並且自動賦值。