四、 数据标签
数据标签主要用于提供各种数据访问相关的功能。
包含如下几个:
● action : 用于在 JSP 中 直接调用一个 Action,通过指定 executeResult 参数,还可将该 Action 的处理结果包含到本页面中来
● bean : 创建一个 JavaBean 实例,如果指定 var ,可放入 Stack Context 中
● date : 格式化输出一个日期
● debug : 用于在页面上生成一个调试链接,点击后,显示当前 ValueStack 和 Stack Context 中的内容
● i18n : 指定国际化资源文件的 baseName
● include : 在 JSP 页面中包含其他的 JSP 或 Servlet 资源。
● param : 设置一个参数,通常是用做 bean 标签、url 标签的子标签。
● push : 用于将某个值放入 ValueStack 栈顶
● set : 用于设置一个新的变量,并可以将新变量放入指定的范围内。
● text : 用于输出国际化消息。
● url : 用于生成一个 URL 地址。
● property : 用于输出某个值,包括输出 ValueStack、Stack Context 和 Action Context 中的值。
4.1 action 标签
action 用于在 JSP 中 直接调用一个 Action,可以指定被调用 Action 的 name 和 namespace。通过指定 executeResult 参数,还可将该 Action 的处理结果包含到本页面中来
属性:
● var : 可选。 一旦定义了,该 Action 将被放入 ValueStack 中
● name : 必填。 指定调用哪个 Action
● namespace : 可选。 指定调用 Action 的 namespace
● executeResult : 可选。 指定是否要将 Action 的处理结果页面包含到本页面。默认是 false,即不包含
● ignoreContextParams : 可选。 指定该页面中的请求参数是否需要传入调用的 Action 。 默认值是 false ,即将本页面的请求参数传入被调用的 Action
s-action.jsp
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>使用s:action标签在页面中调用Action</title>
<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<h3>下面调用第一个Action,并将结果包含到本页面中。</h3><br/>
<s:action name="tag1" executeResult="true"/>
<br/><br/><br/>
<h3>下面调用第二个Action,并将结果包含到本页面中。<br/>
但阻止本页面请求参数传入Action。<br/></h3>
<s:action name="tag2" executeResult="true" ignoreContextParams="true"/>
<br/><br/><br/>
<h3>下面调用第二个Action,且并不将结果包含到本页面中。<br/>
<s:action name="tag2" executeResult="false"/>
本页面是否可访问?</h3>
<s:property value="author"/>
</body>
</html>
TagAction
package js;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ActionContext;
public class TagAction extends ActionSupport {
// 封装用户请求参数的author属性
private String author;
// author属性的setter和getter方法
public void setAuthor(String author) {
this.author = author;
}
public String getAuthor() {
return this.author;
}
// 定义第一个处理逻辑
public String execute() throws Exception {
return "done";
}
// 定义第二个处理逻辑
public String login() throws Exception {
ActionContext.getContext().put("author", getAuthor());
return "done";
}
}
struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.2.dtd"> <struts> <package name="js" extends="struts-default" namespace="/09"> <!-- 定义第一个Action,使用 js.TagAction 的 execute 方法作为控制处理逻辑 --> <action name="tag1" class="js.TagAction"> <result name="done">/09/succ.jsp</result> </action> <!-- 定义第二个Action,使用 js.TagAction 的 login 方法作为控制处理逻辑 --> <action name="tag2" class="js.TagAction" method="login"> <result name="done">/09/loginSucc.jsp</result> </action> <action name=""> <result>.</result> </action> </package> </struts>
loginSucc.jsp
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>s:action的成功页面</title>
<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<br/>
<s:property value="author"/>,登录成功!!
</body>
</html>
succ.jsp
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>s:action的成功页面</title>
<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<br/>
<s:property value="author"/>,执行成功!!
</body>
</html>
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>struts2</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
function newWin(url){
window.open(url, "newwindow", "width=800,height=500,top="+(screen.availHeight-500)/2+",left="+(screen.availWidth-600)/2+", toolbar=no, menubar=no, scrollbars=yes, resizable=no, location=yes, status=no");
}
</script>
</head>
<body>
<table width="100%" border="0" style="">
<tr><td align="center"><h4>-----链接-----</h4></td></tr>
<tr>
<td>
<s:a href="" οnclick="newWin('09/s-action.jsp?author=js');" cssStyle="cursor: hand;">s-action.jsp</s:a>
</td>
</tr>
</table>
</body>
</html>
4.2 bean 标签
以下所有代码都基于 4.1
bean 标签用于创建一个 JavaBean 实例。可以在该标签内使用 <param .../> 为 JavaBean 实例传入属性,此时 JavaBean 必须提供 setter 方法,如果要得到某个属性,应该提供 getter 方法。
属性:
● name : 必填。指定要实例化的 JavaBean 的实现类
● var : 可选。 如果指定了该属性,则该 JavaBean 实例会被放入 Stack Context 中(不是 ValueStack ),从而允许直接通过 var 属性来访问该
JavaBean
注意: 在 bean 标签的标签体内,bean 标签创建的 JavaBean 实例是位于 ValueStack 栈顶; 但是一旦该 bean 标签结束了,则 bean 标签创建的 JavaBean 实例 被移出 ValueStack 。 除非指定了 var ,则还可以通过 Stack Context 来访问实例。
Person.java
package js;
public class Person {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return this.age;
}
}
s-bean.jsp
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>使用s:bean标签创建JavaBean的实例</title>
<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<h3>使用bean标签创建一个lee.Person类的实例</h3>
<!-- 使用bean标签创建一个lee.Person类的实例 -->
<s:bean name="js.Person">
<!-- 使用param标签为lee.Person类的实例传入参数 -->
<s:param name="name" value="'yeeku'"/>
<s:param name="age" value="29"/>
<!-- 因为在bean标签内,lee.Person实例位于ValueStack的栈顶,
故可以直接访问lee.Person实例 -->
Person实例的name为:<s:property value="name"/><br/>
Person实例的age为:<s:property value="age"/>
</s:bean>
<h3>使用bean标签创建一个lee.Person类的实例,为其指定了var属性</h3>
<!-- 使用bean标签创建一个lee.Person类的实例,为其指定了var属性 -->
<s:bean name="js.Person" var="p">
<!-- 使用param标签为lee.Person类的实例传入参数 -->
<s:param name="name" value="'yeeku111'"/>
<s:param name="age" value="29"/>
</s:bean>
<!-- 根据JavaBean实例指定的var属性来访问JavaBean实例 -->
Person实例的name为:<s:property value="#p.name"/><br/>
Person实例的age为:<s:property value="#p.age"/>
</body>
</html>
4.3 date 标签
以下所有代码都基于 4.1
date 标签用于格式化输出一个日期。 除此之外 ,还能计算指定日期和当前时刻之间的时差
属性:
● format : 可选。如果指定该属性,将根据属性指定的格式来格式化日期
● nice : 可选。 该属性只能是 true 或 false,用于指定是否输出指定日期和当前时刻之间的时差。默认 false, 即不输出时差。
● name : 必填。 指定要格式化的日期值。
● var : 可选。如果指定了该属性,则该时间对象将被放入 ValueStack 中。
通常 nice 属性和 format 属性不同时指定。
注意: 如果既指定了 nice="true" ,也指定了 format 属性,则会输出指定日期和当前时刻之间的时差,即 format 属性失效
如果既没有指定 format ,也没有指定 nice = "true" ,则系统会到国际化资源文件中寻找 key 为 struts.date.format 的消息,将该消息当成格式化文本来格式化日期。如果无法找到此 key ,则默认采用 DateFormat.MEDIUM 格式输出。
s-date.jsp
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>使用s:date标签格式化日期</title>
<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<%
//生成一个Date实例
java.util.Date now = new java.util.Date(107, 12, 23, 13, 23, 24);
//将该Date实例设置成一个pageContext里的属性
pageContext.setAttribute("now" , now);
%>
nice="false",且指定format="dd/MM/yyyy"<br/>
<s:date name="#attr.now" format="dd/MM/yyyy" nice="false"/><br/>
nice="true",且指定format="dd/MM/yyyy"<br/>
<s:date name="#attr.now" format="dd/MM/yyyy" nice="true"/><br/>
指定nice="true"<br/>
<s:date name="#attr.now" nice="true" /><br/>
nice="false",且没有指定format属性,调用 国际化资源文件的 struts.date.format<br/>
<s:date name="#attr.now" nice="false"/><br/>
</body>
</html>
struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.2.dtd"> <struts> <constant name="struts.custom.i18n.resources" value="messageResource"/> <constant name="struts.i18n.encoding" value="GBK"/> <package name="js" extends="struts-default" namespace="/09"> <action name=""> <result>.</result> </action> </package> </struts>
messageResource_en_US.properties
struts.date.format=yyyy/MM/dd
messageResource_zh_CN.properties
struts.date.format=yyyy年MM月dd日
4.4 debug 标签
以下所有代码都基于 4.1
debug 标签主要用于辅助调试,它在页面上生成一个超链接,通过这个链接可以看到 ValueStack 和 Stack Context 中所有的值信息
使用 debug 标签 只有一个 id 属性,这个属性没有太大的意义,只是该元素的一个引用 id
4.5 include 标签
以下所有代码都基于 4.1
i nclude 标签用于将一个 JSP 页面,或者一个 Servlet 包含到本页面中。
属性:
● value : 必填。 指定需要被包含的 JSP 或 Servlet
除此之外,还可以为 <s:include .../> 标签指定了多个 <param .../> 子标签,用于将多个参数值传入被包含的 JSP 或 Servlet
s-include.jsp
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<%@taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>使用s:include标签来包含目标页面</title>
<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<h2>使用s:include标签来包含目标页面</h2>
<!-- 使用include标签来包含其他页面 -->
<s:include value="included-file.jsp"/>
<!-- 使用include标签来包含其他页面,并且传入参数 -->
<s:include value="included-file.jsp">
<s:param name="author" value="'Terry'"/>
</s:include>
<h2>include</h2>
<%@include file="included-file.jsp" %>
<h2>jsp:include</h2>
<jsp:include page="included-file.jsp" flush="true">
<jsp:param name="author" value="ttttttttt" />
</jsp:include>
</body>
</html>
included-file.jsp
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<%@taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>被包含的页面</title>
<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<h3>被包含的页面</h3>
author参数值为:${param.author}
</body>
</html>
<s:a href="" οnclick="newWin('09/s-include.jsp');" cssStyle="cursor: hand;">s-include.jsp</s:a>
4.6 param 标签
以下所有代码都基于 4.1
param 主要用于为其他标签提供参数,例如: 为 include ,bean 标签提供参数
属性 :
● name : 可选,指定需要设置参数的参数名
● value : 可选, 指定需要设置参数的参数值
注意 : name 属性是可选的。如果提供了 name 属性, 则要求 Component 提供该属性的 setter 方法 ; 如果不提供 name 属性,则外层标签必须实现 UnnamedParametric 接口(如 TextTag )
①
<param name="color">blue</param>
上面的用法中,指定一个名为 color 的参数,该参数的值为 blue
②
<param name="color" value="blue"/>
上面用法中,指定一个名为 color 参数, 该参数的值为 blue 对象的值 (如果 blue 对象不存在,则 color 参数的值为 null ) 如果想指定 color 参数的值为 blue 字符串 ,则:
<param name="color" value="'blue'"/>
4.7 push 标签
以下所有代码都基于 4.1
push 标签用于将某个值放到 ValueStack 栈顶,从而可以更简单地访问该值。
属性 :
● value : 必填。指定需要放到 ValueStack 栈顶的值
注意 : 只有在 push 标签内时,被 push 标签放入 ValueStack 中的对象才存在;一旦离开了 push 标签,则刚放入的对象将立即被移除 ValueStack
s-push.jsp
<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %>
<%@taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>使用s:push来将某个值放入ValueStack的栈顶</title>
<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<h2>使用s:push来将某个值放入ValueStack的栈顶</h2>
<!-- 使用bean标签创建一个JavaBean实例,指定var属性,并将其放入Stack Context中 -->
<s:bean name="js.Person" var="p">
<s:param name="name" value="'yeeku'"/>
<s:param name="age" value="29"/>
</s:bean>
<!-- 将Stack Context中的p对象放入ValueStack栈顶-->
<s:push value="#p">
<!-- 输出ValueStack栈顶对象的name和age属性 -->
ValueStack栈顶对象的name属性:<s:property value="name"/><br/>
ValueStack栈顶对象的age属性:<s:property value="age"/><br/>
</s:push>
</body>
</html>
Person.java
package js;
public class Person {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return this.age;
}
}
4.8 set 标签
以下所有代码都基于 4.1
set 标签用于将某个值放入指定范围内,如 application ,session 等。
当某个值所在对象图深度非常深时,例如: person.worker.wife.parent.age ,每次访问该值,不仅性能低下,而且代码可读性也差,为了避免这个问题,可以将该值设置成一个新值,并放入特定的范围内。
提示 : 使用 set 标签可以理解为定义一个新变量,且将一个已有的值复制给新变量,并且可以将新变量放到指定的范围内
属性 :
● scope :可选。 指定新变量被放置的范围 ( application , session , request , page , action 5个值 )。 默认是 action
● value : 可选。 指定将赋给变量的值。如果没有指定该属性,则将 ValueStack 栈顶的值赋给新变量。
● var : 可选。 如果指定了该属性,则会将该值放入 ValueStack 中
如果指定 action 范围,则该值将被放入 request 范围和 Struts 2 的 Stack Context 中
s-set.jsp
<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>使用s:set设置一个新变量</title>
<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<h2>使用s:set设置一个新变量</h2>
<!-- 使用bean标签定义一个JavaBean实例 -->
<s:bean name="js.Person" id="p">
<s:param name="name" value="'yeeku'"/>
<s:param name="age" value="29"/>
</s:bean>
将Stack Context中的p值放入默认范围(action)内。<br />
<s:set value="#p" name="xxx"/>
Stack Context内xxx对象的name属性:<s:property value="#xxx.name"/><br />
Stack Context内xxx对象的age属性:<s:property value="#xxx.age"/><br />
request范围的xxx对象的name属性:${requestScope.xxx.name}<br />
request范围的xxx对象的age属性:${requestScope.xxx.age}<hr />
将Stack Context中的p值放入application范围内。<br />
<s:set value="#p" name="xxx" scope="application"/>
application范围的xxx对象的name属性:${applicationScope.xxx.name}<br />
application范围的xxx对象的age属性:${applicationScope.xxx.age}<hr />
将Stack Context中的p值放入session范围内。<br/>
<s:set value="#p" name="xxx" scope="session"/>
<!-- JSP 2.0 表达式语言直接访问 session 中的属性 -->
session范围的xxx对象的name属性:${sessionScope.xxx.name}<br />
session范围的xxx对象的age属性:${sessionScope.xxx.age}
</body>
</html>
Person.java
package js;
public class Person {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return this.age;
}
}
4.9 url 标签
以下所有代码都基于 4.1
url 标签用于生成一个 URL 地址,可以通过为 url 指定 param 子元素,指定 URL 发送请求参数。
属性 :
● action : 可选。 指定生成 URL 的地址为哪个 Action,如果不提供,就是使用 value 作为 URL 的地址值。
● anchor : 可选。 指定 URL 的 锚点。
● encode : 可选。 指定是否需要对参数进行编码,默认是 true
● escapeAmp : 可选。 指定是否需要对 & 符号进行编码,默认是 true
● forceAddSchemeHostAndPort : 可选。 指定是否需要在 URL 对应的地址里强制添加 scheme 、 主机和端口
● includeContext : 可选。 指定是否需要将当前上下文包含在 URL 地址中
● includeParams : 可选。 指定是否包含请求参数,该属性的属性值只能为 none、 get 或者 all。默认 get
● method : 可选。 指定 Action 的方法。当用 action 生成 URL 时,将链接到指定 Action 的特定方法。
● namespace : 可选。 指定命名空间,当用 Action 生成 URL 时, URL 将链接到此 namespace 的指定 Action 处
● portletMode : 可选。 指定结果页面的 portlet 模式。
● scheme : 可选。 用于设置 scheme 属性。
● value : 可选。 指定生成 URL 的地址值,如果 value 不提供就用 action 属性指定的 Action 作为 URL
● var : 可选。如果指定了,将该链接值 放入 Struts 2 的 ValueStack 中
● windowState : 可选。指定结果页面的 portlet 的窗口状态.
注意 : 上面的 action 属性和 value 属性的作用大致相同,只是 action 指定的是一个 Action,系统会自动添加 .action 后缀. 只要指定 action 和 value 其中之一即可,如果2个都没指定,就以当前页面作为 URL 值
提示 : portletMode 和 windowState 都需要结合 Struts 2 的 Portlet 功能才有用
s-url.jsp
<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>使用s:url来生成一个URL地址</title>
<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<h2>s:url来生成一个URL地址</h2>
只指定value属性的形式。<br/>
<s:url value="editGadget.action"/>
<hr/>
指定action属性,且使用param传入参数的形式。<br/>
<s:url action="showBook">
<s:param name="author" value="'yeeku'" />
</s:url>
<hr/>
既不指定action属性,也不指定value属性,且使用param传入参数的形式。<br/>
<s:url includeParams="get" >
<s:param name="id" value="%{'22'}"/>
</s:url>
<hr/>
同时指定action属性和value属性,且使用param传入参数的形式。<br/>
<s:url action="showBook" value="xxxx">
<s:param name="author" value="'yeeku'" />
</s:url>
</body>
</html>
<s:a href="" οnclick="newWin('09/s-url.jsp');" cssStyle="cursor: hand;">s-url.jsp</s:a>
4.10 property 标签
以下所有代码都基于 4.1
property 标签的作用就是输出指定值。输出 value 属性指定的值,如果没有指定 value 属性,默认输出 ValueStack 栈顶值。
属性:
● default : 可选。如果需要输出的属性值为 null ,则显示的 default 属性值
● escape : 可选,指定是否 escape HTML 代码。 默认 true
● value : 可选, 指定需要输出的属性值,如果没有指定该属性,默认输出 ValueStack 栈顶值
五、 主题和模版
模版是一个 UI 标签的外在表示形式,例如:使用 <s:select .../> 时,Struts 2 就会根据对应 select 模版来生成一个有模版特色的下拉框列表。如果所有 UT 标签都提供了对应的模版,那么这系列的模版就会形成一个主题
5.1 选择主题
主题是模版的组织形式,模版被包装在主题里面,对开发者应该是透明的。当需要使用特定模版来表现某个 UI 标签时,应该让主题来负责模版的加载
设置主题的方法有如下几种:
① 通过设定特定 UI 标签上的 theme 属性指定主题
② 通过设定特定 UT 标签外围的 Form 标签的 theme 属性来指定主题
③ 通过取得 page 会话范围内以 theme 的属性来确定主题
④ 通过取得 request 范围内的命名为 theme 的属性来确定主题
⑤ 通过取得 session 范围内的命名为 theme 的属性来确定主题
⑥ 通过取得 application 范围内的命名为 theme 的属性来确定主题
⑦ 通过设置名为 struts.ui.theme 的常量(默认是 xhtml ) 来确定默认主题,可以在 struts.properties 或者 struts.xml 文件中确定
上面的几种指定特定 UI 标签主题的方式,有着不同优先级 ,排在前面的方式会覆盖排在后面的方式。
Struts 2 允许在一个视图页面中使用几种不同的主题。
建议:
● 如果需要改变整个表单 (包括表单元素的主题),则可以直接设置该表单标签的 theme 属性
● 如果需要让某次用户会话使用特定的主题,则可以通过在 session 中设置一个 theme 的变量
● 如果想改变整个应用的主题,则应该通过修改 struts.ui.theme 常量值来实现
Struts 2 的模版目录是通过 struts.ui.templateDir 常量来指定,该常量的默认值是 template ,即意味着 Struts 2 会从 web 应用的 template 目录、 CLASSPATH (包括 Web 应用的 WEB-INF/classes 路径和 WEB-INF/lib 路径)的 template 目录来依次加载特定模版文件。
例如:使用一个 select 标签,并且指定主题为 xhtml, 则加载模版文件的顺序为:
① 搜索 web 应用里 /template/xhtml/select.ftl
② 搜索 CLASSPATH 路径下的 /template/xhtml/select.ftl
*.ftl 文件是 FreeMarker 模版文件,Struts 2 使用 FreeMarker 技术来定义所有模版文件。因此,如果开发者需要扩展自己的模版,也推荐使用 FreeMarker 来开发自定义模版。
Struts 2 也可以选择自己的模版技术,通过修改 struts.ui.templateSuffix 常量的值,就可以改变 Struts 2 默认的模版技术
● ftl(默认) : 基于 FreeMarker
● vm : 基于 Velocity
● jsp : 基于 JSP
提示 : 通常不推荐开发者完成实现自己的模版和主题,而应该对原有主题进行扩展,因此,开发者只有选择原有的 FreeMarker 作为模版技术。 FreeMarker 是一个非常简单、易用的模版语言,完全可以取代 JSP 作为表现层技术。
Struts 2 提供了 3 个主题: simple 、 xhtml 和 css_xhtml ,打开 struts2-core-2.2.1.jar ,看到一个 template 文件夹,该文件夹下面包含了 simple 、 xhtml 、 css_xhtml 三个文件夹,这三个文件夹分别对应三种主题。
从 Struts 2.1 开始 Struts 2 核心包不再提供 Ajax 主题,而是由 struts2-dojo-plugin-2.2.1.jar 来提供 Ajax 主题
simple 主题是最简单的主题,是最底层的结构,主要用于构建附加的功能或者行为(例如:在此主题基础上进行扩展)。使用 simple 主题时,每个 UI 标签值生成一个简单的 HTML 元素,不会生成其他额外的内容。
Struts 2 的 xhtml 和 css_xhtml 都是对 simple 主题的包装和扩展。
xhtml 是 Struts 2 默认主题,它对 simple 主题进行扩展,附加如下特性:
● 针对 HTML 标签 (如 textfield 和 select 标签) 使用标准的两列表格布局
● 每个 HTML 标签的 label,既可以出现在 HTML 元素的左边,也可以出现在其上边,这取决于 labelposition 属性的设置
● 自动输出校验错误提示
● 输出 JavaScript 的客户端校验。
css_xhtml 主题则对原有的 xhtml 主题进行了扩展,在 xhtml 主题基础上加入了 CSS 样式控制 。
5.2 自定义主题
自定义主题有 3 种方式:
● 开发者完全实现一个全新的主题
● 包装一个现有的主题
● 扩展一个现有的主题
对于开发者完全实现一个新的主题 。例如 改换 JSP 或者Velocity 作为模版技术。但这种方式需要开发者为每个UI 标签提供自定义模版文件,工作量巨大,不推荐
Struts 2 允许通过对现有主题进行包装来创建自定义主题。
系统的 xhtml 主题就大量使用了包装技术, xhtml 主题下的模版文件可能包含如下片段:
<#include "/${parameters.templateDir}/simple/xxx.ftl" />
这个模版包装了 simple 主题下已存在的模版,从而为原有模版增加了额外的技术
注意 : 使用纯粹的包装方法来创建主题时,开发者必须为每个 UI 组建都提供自定义主题的模版文件,即自定义主题里某个 UI 组件与原来主题里 UI 组件的行为完全一样。
Struts 2 允许对现有的主题进行扩展,开发者只需要提供自定义的模版文件。例如: 以 xhtml 为基础,只想改变 select UI 标签行为,可以提供一个自己的 select.ftl 文件。
\WEB-INF\src\template\lee\select.ftl
<h3>作者李刚已经出版的图书:</h3> <#include "/${parameters.templateDir}/xhtml/controlheader.ftl" /> <#include "/${parameters.templateDir}/simple/select.ftl" /> <#include "/${parameters.templateDir}/xhtml/controlfooter.ftl" />
除此之外,还必须在主题目录下增加一个 theme.properties 文件,指定自定义模版是以哪个模版为基础扩展的。
\WEB-INF\src\template\lee\theme.properties
parent=xhtml
s-select.jsp
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<%@taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>使用自定义模板来生成下拉列表</title>
<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<!-- 使用select标签生成一个列表框,指定使用lee的主题 -->
<s:select name="aa" theme="lee" list="{'Struts 2权威指南','轻量级Java EEE企业应用实战','疯狂Ajax讲义',
'疯狂Java讲义'}" size="5"/>
</body>
</html>
<s:a href="" οnclick="newWin('09/s-select.jsp');" cssStyle="cursor: hand;">s-select.jsp</s:a>
因为在 select 模版文件中增加了一个标题,故此处页面中的下拉列表也增加了一个标题 (“作者李刚已经出版的图书:” 这个标题是通过主题生成的,不是直接写在这里的 )
Struts 2 的主题、模版技术非常优秀 : 每个应用中总有大量表单、表现层组件,它们有相似的外观,在传统的 Web 开发过程中,我们不得不在各页面重复定义这些,但是使用了 Struts 2 之后,我们就可以把它们定义成自定义主题的模版,然后就可以重复使用它们了,这样就可以提供极好的代码复用。