Struts 2 的标签库(三)
?
?
四、 数据标签
?
?? 数据标签主要用于提供各种数据访问相关的功能。
?
包含如下几个:
?
● 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" 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="" onclick="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
?
include 标签用于将一个 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="" onclick="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="" onclick="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="" onclick="newWin('09/s-select.jsp');" cssStyle="cursor: hand;">s-select.jsp</s:a>?因为在 select 模版文件中增加了一个标题,故此处页面中的下拉列表也增加了一个标题 (“作者李刚已经出版的图书:” 这个标题是通过主题生成的,不是直接写在这里的)
Struts 2 的主题、模版技术非常优秀 : 每个应用中总有大量表单、表现层组件,它们有相似的外观,在传统的 Web 开发过程中,我们不得不在各页面重复定义这些,但是使用了 Struts 2 之后,我们就可以把它们定义成自定义主题的模版,然后就可以重复使用它们了,这样就可以提供极好的代码复用。
?