??xml version="1.0" encoding="utf-8" standalone="yes"?>97精品在线,亚洲高清视频在线观看,欧美激情理论http://www.aygfsteel.com/wjywilliam/category/35145.htmlConsciousness Of Programming - wjywilliam 想飞QL?x)飞?..... zh-cnThu, 09 Jun 2011 18:16:49 GMTThu, 09 Jun 2011 18:16:49 GMT60FreeMarkerҎ(gu)介l与概述http://www.aygfsteel.com/wjywilliam/articles/351928.htmlwjywilliamwjywilliamWed, 08 Jun 2011 09:46:00 GMThttp://www.aygfsteel.com/wjywilliam/articles/351928.htmlhttp://www.aygfsteel.com/wjywilliam/comments/351928.htmlhttp://www.aygfsteel.com/wjywilliam/articles/351928.html#Feedback0http://www.aygfsteel.com/wjywilliam/comments/commentRss/351928.htmlhttp://www.aygfsteel.com/wjywilliam/services/trackbacks/351928.html 一QFreemarker?br />
二.环境搭徏与配|?/strong>

三.常用语法

四.与Strutsl合

五.生成Html面


一QFreemarker?br /> 什么是Freemarker:.

Freemaker是一个”模板引擎?也可以说是一个基于模板技术的生成文本输出的一个通用工具.它是一个JAVA的包,一个JAVAE序员可以用的

cd.本nq不是一个对最l用L(fng)应用E序.但是,E序员可以把它应用到他们的品中.

FreeMarker是设计ؓ(f)可以生成WEB PAGES.它是ZSERVLET遵@MVC模式?q个思\是应用MVC模式要降低分?|页设计人员和程序员的耦合.

每个人都可以做他们擅长的工作.|页设计人员可以改变|页的面?而ƈ不需要程序员的重新编?因ؓ(f)业务逻辑和页面的设计已经被分d?/p>

.模板是不能由复杂的程序片断组成的.即便|页设计人员和程序员是一个h. 分离是有必要?它能使程序更加的灉|和清?

虽然Freemarker能编E?但是它ƈ不是一个编E语a.它是为程序显C数据而准备的.(像数据库SQL语句的查?)以及(qing).Freemarker仅仅是利用模

板加上数据生成文本页?

Freemarkerq不是一个WEB应用E序框架.可以说是一个WEB应用框架的一个组?但是FREEMARKER引擎本nq不?jin)解HTTP或者SERVLETS.它只不过

生成文本而已.注意,它是MVC框架的一个组?如STRUTS),也可以在模板中用JSP标签.

 (tng) Freemarker下蝲地址为:(x)http://www.freemarker.org/index.html

一般的用?

l 能用来生成Q意格式的文本:HTML,XML,RTF,JAVA源码,{等.

l可以更好的嵌入到你的产品?轻量U的.q不需要servlet环境.不依赖javax.servlet.classes.

l可插入的模板d?你可以从L的源码读取Q意的模板.本地的文?数据库等{?

l你可以做L你想生成的文?存储为本地文?可以用来发送EMAIL或返回到WEB览器中.

 (tng)

强大的模板语a

l完整的指?include,if/elseif/else,loop.

l 建立和修Ҏ(gu)板中的变?

l 能用复杂的表辑ּ在Q意地Ҏ(gu)定变?

n字符串操?concateration,sub-string,uppercase,capitalize,escaping.{等

n十进制数学计?

n BOOL

nd数组和相关的数组元素.

n可以自己dҎ(gu)的计方?

l宏指?/p>

l 命名I间用来创徏和维护宏指o(h)库或者把大的目分成许多模块.q不用担?j)命名冲H?br />

----------------------------------------------------------------------------
二.环境搭徏与配|?br />
<!—freemarker初始配置-->
 (tng)
<servlet>
<servlet-name>freemarker</servlet-name>
<servlet-class>freemarker.ext.servlet.FreemarkerServlet</servlet-class>
<init-param>
<param-name>TemplatePath</param-name>
<param-value>/</param-value>
</init-param>
<init-param>
<param-name>NoCache</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>ContentType</param-name>
<param-value>text/html</param-value>
</init-param>
<init-param>
<param-name>template_update_delay</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>default_encoding</param-name>
<param-value>GBK</param-value>
</init-param>
<init-param>
<param-name>locale</param-name>
<param-value>zh_CN </param-value>
</init-param>
<init-param>
<param-name>number_format</param-name>
<param-value>0.##########</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>freemarker</servlet-name>
<url-pattern>*.ftl</url-pattern>
</servlet-mapping>
 (tng)
----------------------------------------------------------------------------
三.常用语法
 (tng)EG.一个对象BOOK


 (tng) 1.输出 ${book.name}

I值判断:(x)${book.name?if_exists },

${book.name?default(‘xxx?}//默认值xxx
${ book.name!"xxx"}//默认值xxx

日期格式Q?{book.date?string('yyyy-MM-dd')}

数字格式Q?{book?string.number}--20
${book?string.currency}--<#-- $20.00 -->
${book?string.percent}?lt;#-- 20% -->

插入布尔|(x)
<#assign foo=ture />
${foo?string("yes","no")} <#-- yes -->
 (tng)
 (tng)
 (tng)
 (tng)
2Q逻辑判断
a:
<#if condition>...
<#elseif condition2>...
<#elseif condition3>......
<#else>...
其中I值判断可以写?lt;#if book.name?? >
 (tng)
</#if>


b:
<#switch value>
 (tng) <#case refValue1>
 (tng) (tng) (tng) ...
 (tng) (tng) (tng) <#break>
 (tng) <#case refValue2>
 (tng) (tng) (tng) ...
 (tng) (tng) (tng) <#break>
 (tng) ...
 (tng) <#case refValueN>
 (tng) (tng) (tng) ...
 (tng) (tng) (tng) <#break>
 (tng) <#default>
 (tng) (tng) (tng) ...
</#switch>
 (tng)
3Q@环读?br /><#list sequence as item>
...
</#list>
I值判?lt;#if bookList?size = 0></#list>


e.g.
<#list employees as e>
${e_index}. ${e.name}
</#list>
输出:
1. Readonly
2. Robbin


4.FreeMarker


4 (tng)?模板

宏Macro

宏是在模板中使用macro指o(h)定义
l.1 基本用法
宏是和某个变量关联的模板片断Q以便在模板中通过用户定义指o(h)使用该变量,下面是一个例子:(x)

<#macro greet>
 (tng) <font size="+2">Hello Joe!</font>
</#macro>

调用宏时Q与使用FreeMarker的其他指令类|
 (tng)只是使用@替代FTL标记中的#?/strong>

<@greet></@greet>

<#--<@greet/>-->


在macro指o(h)中可以在宏变量之后定义参?/strong>Q如Q?/p>

<#macro greet person>
 (tng) <font size="+2">Hello ${person}!</font>
</#macro>
 (tng)可以q样使用q个宏变量:(x)
 (tng) (tng)<@greet person="Fred"/>
 (tng)但是下面的代码具有不同的意思:(x)
 (tng) (tng)<@greet person=Fred/>
 (tng)q意味着Fred变量的glperson参数Q该g仅是字符Ԍq可以是其它cdQ甚x(chng)复杂的表辑ּ?/p>


宏可以有多参敎ͼ下面是一个例?/strong>Q?br /><#macro greet person color>
 (tng) <font size="+2" color="${color}">Hello ${person}!</font>
</#macro>

可以q样使用该宏变量Q其中参数的ơ序是无关的Q?br /><@greet person="Fred" color="black"/>

可以在定义参数时指定~省|否则Q在调用宏的时候,必须Ҏ(gu)有参数赋|(x)
<#macro greet person color="black">
 (tng) <font size="+2" color="${color}">Hello ${person}!</font>
</#macro>

注意Q宏的参数是局部变量,只能在宏定义中有效?/p>


在宏里嵌套内?br />FreeMarker的宏可以有嵌套内容,
<#nested>指o(h)?x)执行宏调用指o(h)开始和l束标记之间的模板片断,举一个简单的例子Q?/p>

<#macro border>
 (tng) <table border=4 cellspacing=0 cellpadding=4><tr><td>
 (tng) (tng) (tng) <#nested>
 (tng) </tr></td></table>
</#macro>

执行宏调用:(x)
<@border>The bordered text</@border>
输出l果Q?br /><table border=4 cellspacing=0 cellpadding=4>
 (tng)<tr><td>
 (tng) (tng) (tng)  (tng) (tng)The bordered text
 (tng)  (tng)</tr></td>
</table>

<#nested>指o(h)可以被多ơ调用,每次都会(x)执行相同的内宏V?br /><#macro do_thrice>
 (tng) <#nested>
 (tng) <#nested>
 (tng) <#nested>
</#macro>


<@do_thrice>
 (tng) Anything.
</@do_thrice>

FMPP 输出l果Q?br />Anything.
Anything.
Anything.

嵌套内容可以是有效的FTLQ下面是一个有些复杂的例子Q我们将上面三个宏组合v来:(x)
<@border>
 (tng) <ul>
 (tng) <@do_thrice>
 (tng) (tng) (tng) <li><@greet person="Joe"/>
 (tng) </@do_thrice>
 (tng) </ul>
</@border>
输出l果Q?br /><table border=4 cellspacing=0 cellpadding=4><tr><td>
 (tng) <ul>
 (tng) (tng) (tng) <li><font size="+2">Hello Joe!</font>
 (tng) (tng) (tng) <li><font size="+2">Hello Joe!</font>
 (tng) (tng) (tng) <li><font size="+2">Hello Joe!</font>
 (tng) </ul>
 (tng) </tr></td></table>

宏定义中的局部变量对嵌套内容是不可见?/strong>Q例如:(x)
<#macro repeat count>
 (tng) <#local y = "test">
 (tng) <#list 1..count as x>
 (tng) (tng) (tng) ${y} ${count}/${x}: <#nested>
 (tng) </#list>
</#macro>

<@repeat count=3>${y?default("?")} ${x?default("?")} ${count?default("?")}</@repeat>

输出l果Q?br />test 3/1: ? ? ?
test 3/2: ? ? ?
test 3/3: ? ? ?


在宏定义中用@环变?br />nestted指o(h)也可以有循环变量Q@环变量的含义见下节)(j)Q调用宏的时候在宏指令的参数后面依次列出循环变量的名字,格式如下Q?/p>

<@ macro_name paramter list; loop variable list[,]>

例如Q?br /><#macro repeat count>
 (tng) <#list 1..count as x>
 (tng) (tng) (tng) <#nested x, x/2, x==count>
 (tng) </#list>
</#macro>

<@repeat count=4 ; c, halfc, last>
 (tng) ${c}. ${halfc}<#if last> Last!</#if>
</@repeat>

q里count是宏的参敎ͼc, halfc,last则ؓ(f)循环变量Q输出结果:(x)
 (tng) 1. 0.5
 (tng) 2. 1
 (tng) 3. 1.5
 (tng) 4. 2 Last!
循环变量和宏标记指定的不同不?x)有问题Q如果调用时指定了(jin)循环变量Q那么多余的g可见。调用时多指定了(jin)循环变量Q多余的循环变量

不会(x)被创建:(x)
<@repeat count=4 ; c, halfc, last>
 (tng) ${c}. ${halfc}<#if last> Last!</#if>
</@repeat>

<@repeat count=4 ; c, halfc>
 (tng) ${c}. ${halfc}
</@repeat>

<@repeat count=4>
 (tng) Just repeat it...
</@repeat>

在模板中定义变量
在模板中定义的变量有三种cdQ?br />plain变量Q可以在模板的Q何地方访问,包括使用include指o(h)插入的模板,使用assign指o(h)创徏和替换?br />局部变量:(x)在宏定义体中有效Q用local指o(h)创徏和替换?br />循环变量Q只能存在于指o(h)的嵌套内容,由指令(如listQ自动创建;宏的参数是局部变量,而不是@环变?br />局部变量隐藏(而不是覆盖)(j)同名的plain变量Q@环变量隐藏同名的局部变量和plain变量Q下面是一个例子:(x)

<#assign x = "plain">
 (tng)
${x} (tng) <#-- we see the plain var. here -->

<@test/>
 (tng) 6. ${x} (tng) <#-- the value of plain var. was not changed -->
 (tng) <#list ["loop"] as x>
 (tng) 7. ${x} (tng) <#-- now the loop var. hides the plain var. -->
 (tng) (tng) (tng) <#assign x = "plain2"> <#-- replace the plain var, hiding does not mater here -->
 (tng) 8. ${x} (tng) <#-- it still hides the plain var. -->
 (tng) </#list>
 (tng) 9. ${x} (tng) <#-- the new value of plain var. -->
 (tng) <#macro test>
 (tng) 2. ${x} (tng) <#-- we still see the plain var. here -->
 (tng) <#local x = "local">
 (tng) 3. ${x} (tng) <#-- now the local var. hides it -->
 (tng) <#list ["loop"] as x>
 (tng) (tng) (tng) 4. ${x} (tng) <#-- now the loop var. hides the local var. -->
 (tng) </#list>
 (tng) 5. ${x} (tng) <#-- now we see the local var. again -->
</#macro>
输出l果Q?br /> (tng) 1. plain
 (tng) 2. plain
 (tng) 3. local
 (tng) 4. loop
 (tng) 5. local
 (tng) 6. plain
 (tng) 7. loop
 (tng) 8. loop
 (tng) 9. plain2
内部循环变量隐藏同名的外部@环变量,如:(x)
<#list ["loop 1"] as x>
 (tng) ${x}
 (tng) <#list ["loop 2"] as x>
 (tng) (tng) (tng) ${x}
 (tng) (tng) (tng) <#list ["loop 3"] as x>
 (tng) (tng) (tng) (tng) (tng) ${x}
 (tng) (tng) (tng) </#list>
 (tng) (tng) (tng) ${x}
 (tng) </#list>
 (tng) ${x}
</#list>
输出l果Q?br />loop 1
 (tng) (tng) (tng) loop 2
 (tng) (tng) (tng) (tng) (tng) loop 3
 (tng) (tng) (tng) loop 2
 (tng) loop 1
模板中的变量?x)隐藏(而不是覆盖)(j)数据模型中同名变量,如果需要访问数据模型中的同名变量,使用Ҏ(gu)变量globalQ下面的例子假设数据

模型中的user的值是Big JoeQ?br /><#assign user = "Joe Hider">
${user} (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) <#-- prints: Joe Hider -->
${.globals.user} <#-- prints: Big Joe -->
名字I间
通常情况Q只使用一个名字空_(d)UCؓ(f)d字空_(d)但ؓ(f)?jin)创建可重用的宏、变换器或其它变量的集合Q通常U库Q,必须使用多名字空_(d)

其目的是防止同名冲突
创徏?br />下面是一个创建库的例子(假设保存在lib/my_test.ftl中)(j)Q?br /><#macro copyright date>
 (tng) <p>Copyright (C) ${date} Julia Smith. All rights reserved.
 (tng) <br>Email: ${mail}</p>
</#macro>
<#assign mail = "jsmith@acme.com">
使用import指o(h)导入库到模板中,Freemarker?x)?f)导入的库创徏新的名字I间Qƈ可以通过import指o(h)中指定的散列变量讉K库中的变量:(x)
<#import "/lib/my_test.ftl" as my>
<#assign mail="fred@acme.com">
<@my.copyright date="1999-2002"/>
${my.mail}
${mail}
输出l果Q?br /><p>Copyright (C) 1999-2002 Julia Smith. All rights reserved.
 (tng) <br>Email: mailto:jsmith@acme.com%3C/p>
jsmith@acme.com
fred@acme.com
可以看到例子中用的两个同名变量q没有冲H,因ؓ(f)它们位于不同的名字空间。还可以使用assign指o(h)在导入的名字I间中创建或替代变量

Q下面是一个例子:(x)
<#import "/lib/my_test.ftl" as my>
${my.mail}
<#assign mail="jsmith@other.com" in my>
${my.mail}
输出l果Q?br />jsmith@acme.com
jsmith@other.com
数据模型中的变量M地方都可见,也包括不同的名字I间Q下面是修改的库Q?br /><#macro copyright date>
 (tng) <p>Copyright (C) ${date} ${user}. All rights reserved.</p>
</#macro>
<#assign mail = "mailto:$%7Buser%7D@acme.com">
假设数据模型中的user变量的值是FredQ则下面的代码:(x)
<#import "/lib/my_test.ftl" as my>
<@my.copyright date="1999-2002"/>
${my.mail}
输出l果Q?br /><p>Copyright (C) 1999-2002 Fred. All rights reserved.</p>Fred@acme.com


----------------------------------------------------------------------------
四.Freemarker与Strutsl合

1.输出文g换成以ftl格式的文?/p>

E.G.

<action name="bookActionForm" parameter="method" path="/bookAction" scope="request" type="example.BookAction"

validate="true">

<forward name="list" path="/index.ftl"/>

</action>

2.使用strutsQjstl{标{?/p>

a.导入à<#global html=JspTaglibs["/WEB-INF/tags/struts-html.tld"]>

?lt;#assign html=JspTaglibs["/WEB-INF/struts-html.tld"]>
<#assign bean=JspTaglibs["/WEB-INF/struts-bean.tld"]>
<#assign logic=JspTaglibs["/WEB-INF/struts-logic.tld"]>

b.使用à<@bean.page id="request" property="request"/>,
<@html.text property="vo.newsTitle" styleClass="input1"/>

----------------------------------------------------------------------------
五.用Freemarker生成Html面

 (tng) (tng) 例子QMakeFileManager.java

 (tng)

package example;

import freemarker.template.Configuration;
import java.text.SimpleDateFormat;
import java.io.File;
import freemarker.template.DefaultObjectWrapper;
import java.util.Map;
import java.util.HashMap;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.FileOutputStream;
import freemarker.template.TemplateException;
import java.io.IOException;
import freemarker.template.Template;

public class MakeFileManager {
 (tng) (tng) (tng) public String make(Book book, BookFtl bookFtl) {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) Configuration cfg = new Configuration();//配制

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) String realPath = bookFtl.getRealPath();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) String templatePath = realPath + "/WEB-INF/templates/book";
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) String cDateStr = "book/" +
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) new SimpleDateFormat("yyyyMMdd").format(new java.util.
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) Date());
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) String filePostfix = ".html";
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) String path = realPath + "/" + cDateStr;
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) String fileTimeName = new SimpleDateFormat("yyyyMMddhhmmss").format(new
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) java.util.Date());
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) String returnFileName = cDateStr + "/" + fileTimeName + filePostfix;
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) String fileName = "";
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) File bookDir = new File(path);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) if (bookDir.exists()) {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) fileName = path + "/" + fileTimeName + filePostfix;
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) } else {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) bookDir.mkdirs();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) fileName = path + "/" + fileTimeName + filePostfix;
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) }
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) try {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) //讄freemarker的参?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) cfg.setNumberFormat("0.##########");//生成html文g时web.xml配制无效
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) //cfg.setEncoding();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) cfg.setDirectoryForTemplateLoading(new File(templatePath));
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) cfg.setObjectWrapper(new DefaultObjectWrapper());
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) Template bookTemplate = cfg.getTemplate(bookFtl.getTemplateName());//模板对象
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) Map root = new HashMap();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) root.put("book", book);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) root.put("book2",book);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) Writer out = new OutputStreamWriter(new FileOutputStream(fileName));
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) try {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) bookTemplate.process(root, out);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) } catch (TemplateException e) {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) e.printStackTrace();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) }
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) out.flush();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) } catch (IOException e) {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) e.printStackTrace();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) }
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) return returnFileName;
 (tng) (tng) (tng) }
}



wjywilliam 2011-06-08 17:46 发表评论
]]>
OGNL, JSTL, STRUTS2标签用法CZhttp://www.aygfsteel.com/wjywilliam/articles/349036.htmlwjywilliamwjywilliamTue, 26 Apr 2011 06:24:00 GMThttp://www.aygfsteel.com/wjywilliam/articles/349036.htmlhttp://www.aygfsteel.com/wjywilliam/comments/349036.htmlhttp://www.aygfsteel.com/wjywilliam/articles/349036.html#Feedback0http://www.aygfsteel.com/wjywilliam/comments/commentRss/349036.htmlhttp://www.aygfsteel.com/wjywilliam/services/trackbacks/349036.html
OGNL, JSTL, STRUTS2标签用法CZ Q{载)(j)

取Session中的?/strong>
<c:out value="${sessionScope.user.userId}"></c:out><br> (tng) (tng)
<c:out value="${user.userLoginName}"></c:out><br> (tng) (tng) (tng) (tng)
<s:property value="#session.user.userId"/><br> (tng) (tng)
${session.user.userId}<br> (tng) (tng)
${sessionScope.user.userId}<br> (tng) (tng) (tng) (tng)
基本语法
一、EL?br /> (tng) 1.语法l构
 (tng) (tng) (tng) ${expression}
 (tng) 2.[]?q算W?br /> (tng) (tng) (tng) EL 提供.和[]两种q算W来存取数据?br /> (tng) (tng) (tng) 当要存取的属性名UC包含一些特D字W,??{ƈ非字母或数字的符P׃定要使用 []。例如:(x)
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) ${user.My-Name}应当改ؓ(f)${user["My-Name"] }
 (tng) (tng) (tng) 如果要动态取值时Q就可以用[]来做Q?无法做到动态取倹{例如:(x)
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) ${sessionScope.user[data]}中data 是一个变?br /> (tng) 3.变量
 (tng) (tng) (tng) EL存取变量数据的方法很单,例如Q?{username}。它的意思是取出某一范围中名UCؓ(f)username的变量?br /> (tng) (tng) (tng) 因ؓ(f)我们q没有指定哪一个范围的usernameQ所以它?x)依序从Page、Request、Session、Application范围查找?br /> (tng) (tng) (tng) 假如途中扑ֈusernameQ就直接回传Q不再l找下去Q但是假如全部的范围都没有找到时Q就回传null?br /> (tng) (tng) (tng) 属性范围在EL中的名称
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) Page (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)pageScope
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) Request (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) requestScope
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) Session (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) sessionScope
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) Application (tng) (tng) (tng) (tng) applicationScope
 (tng) (tng) (tng) (tng) (tng) (tng) (tng)
二、EL隐含对象
 (tng) 1.与范围有关的隐含对象
 (tng) 与范围有关的EL 隐含对象包含以下四个QpageScope、requestScope、sessionScope 和applicationScopeQ?br /> (tng) 它们基本上就和JSP的pageContext、request、session和application一P
 (tng) 在EL中,q四个隐含对象只能用来取得范围属性|即getAttribute(String name)Q却不能取得其他相关信息?br /> (tng)
 (tng) 例如Q我们要取得session中储存(sh)个属性username的|可以利用下列Ҏ(gu)Q?br /> (tng) (tng) (tng) session.getAttribute("username") 取得username的|
 (tng) 在EL中则使用下列Ҏ(gu)
 (tng) (tng) (tng) ${sessionScope.username}
 (tng) 2.与输入有关的隐含对象
 (tng) 与输入有关的隐含对象有两个:(x)param和paramValuesQ它们是EL中比较特别的隐含对象?br /> (tng)
 (tng) 例如我们要取得用L(fng)h参数Ӟ可以利用下列Ҏ(gu)Q?br /> (tng) (tng) (tng) request.getParameter(String name)
 (tng) (tng) (tng) request.getParameterValues(String name)
 (tng) 在EL中则可以使用param和paramValues两者来取得数据?br /> (tng) (tng) (tng) ${param.name}
 (tng) (tng) (tng) ${paramValues.name}

 (tng) 3.其他隐含对象 (tng) (tng)
 (tng) cookie
 (tng) JSTLq没有提供设定cookie的动作,
 (tng) 例:(x)要取得cookie中有一个设定名UCؓ(f)userCountry的|可以使用${cookie.userCountry}来取得它?/div>
 (tng) header和headerValues
 (tng) header 储存用户览器和服务端用来沟通的数据
 (tng) 例:(x)要取得用h览器的版本,可以使用${header["User-Agent"]}?br /> (tng) 另外在鲜机?x)下Q有可能同一标头名称拥有不同的|此时必须改ؓ(f)使用headerValues 来取得这些倹{?/div>
 (tng) initParam
 (tng) initParam取得讑֮web站点的环境参?Context)
 (tng) 例:(x)一般的Ҏ(gu)String userid = (String)application.getInitParameter("userid");
 (tng) (tng) (tng) 可以使用 ${initParam.userid}来取得名UCؓ(f)userid
 (tng) pageContext
 (tng) pageContext取得其他有关用户要求或页面的详细信息?br /> (tng) (tng) (tng) ${pageContext.request.queryString} (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) 取得h的参数字W串
 (tng) (tng) (tng) ${pageContext.request.requestURL} (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) 取得h的URLQ但不包括请求之参数字符?br /> (tng) (tng) (tng) ${pageContext.request.contextPath} (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) 服务的web application 的名U?br /> (tng) (tng) (tng) ${pageContext.request.method} (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) 取得HTTP 的方?GET、POST)
 (tng) (tng) (tng) ${pageContext.request.protocol} (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) 取得使用的协?HTTP/1.1、HTTP/1.0)
 (tng) (tng) (tng) ${pageContext.request.remoteUser} (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) 取得用户名称
 (tng) (tng) (tng) ${pageContext.request.remoteAddr } (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) 取得用户的IP 地址
 (tng) (tng) (tng) ${pageContext.session.new} (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) 判断session 是否为新?br /> (tng) (tng) (tng) ${pageContext.session.id} (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) 取得session 的ID
 (tng) (tng) (tng) ${pageContext.servletContext.serverInfo} (tng) (tng) 取得L端的服务信息

三、ELq算W?/strong>
 (tng) 1.术q算W有五个Q?????或div?或mod
 (tng) 2.关系q算W有六个Q?=或eq?=或ne?lt;或lt?gt;或gt?lt;=或le?gt;=或ge
 (tng) 3.逻辑q算W有三个Q?amp;&或and、||或or?或not
 (tng) 4.其它q算W有三个QEmptyq算W、条件运符?)q算W?br /> (tng) (tng) (tng) 例:(x)${empty param.name}?{A?B:C}?{A*(B+C)}
 (tng)
四、EL函数(functions)
 (tng) 语法Qns:function( arg1, arg2, arg3 ? argN)
 (tng) 其中ns为前|名U?prefix)Q它必须和taglib 指o(h)的前|名UC|?/div>
Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q?/div>
补充Q?/strong>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
FOREACH:
<c:forEach items="${messages}"
var="item"
begin="0"
end="9"
step="1"
varStatus="var">
…?br /></c:forEach>
 (tng)

OUT:
<c:out value="${logininfo.username}"/>
c:out>value 中的内容输出到当前位|,q里也就是把logininfo 对象?br />username属性D出到面当前位置?br />${……}是JSP2.0 中的Expression LanguageQELQ的语法。它定义?jin)一个表辑ּQ?br />其中的表辑ּ可以是一个常量(如上Q,也可以是一个具体的表达语句Q如forEach循环体中
的情况)(j)。典型案例如下:(x)
? ${logininfo.username}
q表明引用logininfo 对象的username 属性。我们可以通过?”操作符?br />用对象的属性,也可以用“[]”引用对象属性,?{logininfo[username]}
?{logininfo.username}辑ֈ?jin)同L(fng)效果?br />“[]”引用方式的意义在于Q如果属性名中出C(jin)Ҏ(gu)字符Q如?”或者?”,
此时必M用“[]”获取属性g避免语法上的冲突Q系l开发时应尽量避?br />q一现象的出玎ͼ(j)?br />与之{同的JSP Script大致如下Q?br />LoginInfo logininfo =
(LoginInfo)session.getAttribute(“logininfo?;
String username = logininfo.getUsername();
可以看到QEL大大节省?jin)编码量?br />q里引出的另外一个问题就是,EL 从哪里扑ֈl(f)ogininfo 对象Q对?br />${logininfo.username}q样的表辑ּ而言Q首先会(x)从当前页面中L之前?br />否定义了(jin)变量logininfoQ如果没有找到则依次到Request、Session?br />Application 范围内寻找,直到扑ֈ为止。如果直到最后依然没有找到匹配的
变量Q则q回null.
如果我们需要指定变量的L范围Q可以在EL表达式中指定搜寻范围Q?br />${pageScope.logininfo.username}
${requestScope.logininfo.username}
${sessionScope.logininfo.username}
${applicationScope.logininfo.username}
在Spring 中,所有逻辑处理单元q回的结果数据,都将作ؓ(f)Attribute 被放
|到HttpServletRequest 对象中返回(具体实现可参见Spring 源码?br />org.springframework.web.servlet.view.InternalResourceView.
exposeModelAsRequestAttributesҎ(gu)的实C码)(j)Q也是说Spring
MVC 中,l果数据对象默认都是requestScope。因此,在Spring MVC 中,
以下dҎ(gu)应慎用:(x)
${sessionScope.logininfo.username}
${applicationScope.logininfo.username}
? ${1Q?}
l果辑ּ计算l果Q即整数??br />? ${i>1}
如果变量值i>1的话Q将q回boolcdtrue。与上例比较Q可以发现EL?x)?br />动根据表辑ּ计算l果q回不同的数据类型?br />表达式的写法与java代码中的表达式编写方式大致相同?/div>
 (tng)
IF / CHOOSE:
<c:if test="${var.index % 2 == 0}">
*
</c:if>
判定条g一般ؓ(f)一个EL表达式?br /><c:if>q没有提供else子句Q用的时候可能有些不便,此时我们可以通过<c:choose>
tag来达到类似的目的Q?br /><c:choose>
<c:when test="${var.index % 2 == 0}">
*
</c:when>
<c:otherwise>
!
</c:otherwise>
</c:choose>
cMJava 中的switch 语句Q?lt;c:choose>提供?jin)复杂判定条件下的简化处理手法。其
?lt;c:when>子句cMcase子句Q可以出现多ơ。上面的代码Q在奇数行时输出?”号Q?br />而偶数行时输出?”?br />Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q?/div>
再补充:(x)
 (tng)1 (tng) (tng) (tng) EL表达式用${}表示,可用在所有的HTML和JSP标签?作用是代替JSP面中复杂的JAVA代码.
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) 2 (tng) (tng) EL表达式可操作帔R 变量 和隐式对? 最常用?隐式对象?{param}?{paramValues}. ${param}表示q回h参数中单个字W串的? ${paramValues}表示q回h参数的一l?pageScope表示面范围的变?requestScope表示h对象的变? sessionScope表示?x)话范围内的变?applicationScope表示应用范围的变?
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) 3 (tng) (tng) <%@ (tng) page isELIgnored="true"%> 表示是否用EL语言,TRUE表示止.FALSE表示不禁?JSP2.0中默认的启用EL语言.
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) 4 (tng) (tng) EL语言可显C?逻辑表达式如${true and false}l果是false (tng) (tng) (tng) 关系表达式如${5>6} l果是false (tng) (tng) (tng) (tng) 术表达式如 ${5+5} l果?0
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) 5 (tng) (tng) EL中的变量搜烦(ch)范围?page request session application (tng) (tng) 点运符(.)?[ ]"都是表示获取变量的?区别是[ ]可以昄非词cȝ变量
 (tng)
 (tng)
 (tng)
 (tng)
OGNL
OGNL是Object Graph Navigation Language的简Uͼ详细相关的信息可以参考:(x)http://www.ognl.org。这里我们只涉及(qing)Struts2框架中对OGNL的基本支持?/div>
 (tng)
OGNL是一个对象,属性的查询语言。在OGNL中有一个类型ؓ(f)Map的ContextQ称Z下文Q,在这个上下文中有一个根元素QrootQ,Ҏ(gu)元素的属性的讉K可以直接使用属性名字,但是对于其他非根元素属性的讉K必须加上Ҏ(gu)W号#?/div>
 (tng)
在Struts2中上下文为ActionContextQ根元素位Value StackQ值堆栈,值堆栈代表了(jin)一族对象而不是一个对象,其中Actioncȝ实例也属于值堆栈的一个)(j)。ActionContext中的内容如下图:(x)
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) |
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) |--application
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) |
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) |--session
context map---|
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) |--value stack(root)
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) |
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) |--request
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) |
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) |--parameters
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) |
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) |--attr (searches page, request, session, then application scopes)
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) |
因ؓ(f)Action实例被放在Value Stack中,而Value Stack又是根元素(rootQ中的一个,所以对Action中的属性的讉K可以不用标?Q而对其他的访问都必须使用#标记?/div>
 (tng)
引用Action的属?/div>
<s:property value="postalCode"/>
ActionContext中的其他非根QrootQ元素的属性可以按照如下的方式讉KQ?/div>
<s:property value="#session.mySessionPropKey"/> or
<s:property value="#session["mySessionPropKey"]"/> or
<s:property value="#request["mySessionPropKey"]/>
 (tng)
Actioncd以用ActionContext中的?rn)态方法来讉KActionContext?/div>
ActionContext.getContext().getSession().put("mySessionPropKey", mySessionObject);
 (tng)
OGNL与CollectionQListsQMapsQSetsQ?/div>
 (tng)
生成List的语法ؓ(f): {e1,e2,e3}.
<s:select label="label" name="name"
list="{'name1','name2','name3'}" value="%{'name2'}" />
上面的代码生成了(jin)一个HTML Select对象Q可选的内容为:(x) name1Qname2Qname3Q默认gؓ(f)Qname2?/div>
 (tng)
生成Map的语法ؓ(f)Q?{key1:value1,key2:value2}.
<s:select label="label" name="name"
list="#{'foo':'foovalue', 'bar':'barvalue'}" />
上面的代码生成了(jin)一个HTML Select对象,foo名字表示的内容ؓ(f)QfoovalueQbar名字表示的内容ؓ(f)Qbarvalue?/div>
 (tng)
判断一个对象是否在List内存在:(x)
<s:if test="'foo' in {'foo','bar'}">
 (tng) (tng) muhahaha
</s:if>
<s:else>
 (tng) (tng) boo
</s:else>
 (tng)
<s:if test="'foo' not in {'foo','bar'}">
 (tng) (tng) muhahaha
</s:if>
<s:else>
 (tng) (tng) boo
</s:else>
 (tng)
取得一个List的一部分Q?/div>
? (tng) –?所有满选择逻辑的对?
^ (tng) - (tng) (tng) W一个满选择逻辑的对?
$ (tng) - (tng) (tng) 最后一个满选择逻辑的对?/div>
例如Q?/div>
person.relatives.{? #this.gender == 'male'}
上述代码取得q个人(personQ所有的h(this.gender==maleQ的亲戚(relatives)
 (tng)
 (tng)
Lambda 表达?/strong>
 (tng)
OGNL支持单的Lambda表达式语法,使用q些语法可以建立单的lambda函数?/div>
 (tng)
例如Q?/div>
Fibonacci:
if n==0 return 0;
elseif n==1 return 1;
else return fib(n-2)+fib(n-1);
fib(0) = 0
fib(1) = 1
fib(11) = 89
 (tng)
OGNL的Lambda表达式如何工作呢Q?/div>
Lambda表达式必L在方括号内部Q?this表示表达式的参数。例如:(x)
<s:property value="#fib =:[#this==0 ? 0 : #this==1 ? 1 : #fib(#this-2)+#fib(#this-1)], #fib(11)" />
 (tng)
#fib =:[#this==0 ? 0 : #this==1 ? 1 : #fib(#this-2)+#fib(#this-1)]定义?jin)一个Lambda表达式,
#fib(11) 调用?jin)这个表辑ּ?/div>
 (tng)
所以上qC码的输出为:(x)89
 (tng)
在JSP2.1?被用作了(jin)JSP ELQ表辑ּ语言Q的Ҏ(gu)记好Q所以对OGNL的用可能导致问题,
一个简单的Ҏ(gu)是禁用JSP2.1的ELҎ(gu),q需要修改web.xml文gQ?/div>
<jsp-config>
 (tng) (tng) (tng) <jsp-property-group>
 (tng) (tng) (tng) (tng) (tng) <url-pattern>*.jsp</url-pattern>
 (tng) (tng) (tng) (tng) (tng) <el-ignored>true</el-ignored>
 (tng) (tng) (tng) </jsp-property-group>
</jsp-config>

 (tng)



wjywilliam 2011-04-26 14:24 发表评论
]]>Struts2: 在javascript中操?datetimepicker 标签控g的?/title><link>http://www.aygfsteel.com/wjywilliam/articles/233919.html</link><dc:creator>wjywilliam</dc:creator><author>wjywilliam</author><pubDate>Sun, 12 Oct 2008 15:18:00 GMT</pubDate><guid>http://www.aygfsteel.com/wjywilliam/articles/233919.html</guid><wfw:comment>http://www.aygfsteel.com/wjywilliam/comments/233919.html</wfw:comment><comments>http://www.aygfsteel.com/wjywilliam/articles/233919.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/wjywilliam/comments/commentRss/233919.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/wjywilliam/services/trackbacks/233919.html</trackback:ping><description><![CDATA[    只有注册用户d后才能阅读该文?a href='http://www.aygfsteel.com/wjywilliam/articles/233919.html'>阅读全文</a><img src ="http://www.aygfsteel.com/wjywilliam/aggbug/233919.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/wjywilliam/" target="_blank">wjywilliam</a> 2008-10-12 23:18 <a href="http://www.aygfsteel.com/wjywilliam/articles/233919.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">߶</a>| <a href="http://" target="_blank">Ȫ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">齭</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ҳ</a>| <a href="http://" target="_blank">Դ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ƾ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank">п</a>| <a href="http://" target="_blank">½</a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank">ָ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">̨</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ǭ</a>| <a href="http://" target="_blank">Ϫ</a>| <a href="http://" target="_blank">¡</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">˳</a>| <a href="http://" target="_blank">״</a>| <a href="http://" target="_blank">ά</a>| <a href="http://" target="_blank">׼</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ȳ</a>| <a href="http://" target="_blank">ó</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">߮</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>