文档库 最新最全的文档下载
当前位置:文档库 › Freemarker教程 中文版

Freemarker教程 中文版

Freemarker教程 中文版
Freemarker教程 中文版

FreeMarker2.3.10

―Programmer's Guide(中文版)

前言 (3)

一、快速入门 (4)

1.1、创建配置实例 (4)

1.2、创建数据模型(Data Model) (4)

1.3、获取模版(template) (5)

1.4、把模版与数据模型合并 (6)

1.5、完整的代码 (6)

二、数据模型(Data Model) (7)

2.1、基础类型 (7)

2.2、Scalar类型(单值对应的Data Model) (8)

2.3、容器类型 (8)

2.4、方法变量 (9)

2.5、转换器变量 (10)

2.6、节点变量 (12)

2.7、对象包裹 (12)

三、配置(Configuration) (15)

3.1、基础 (15)

3.2、共享变量 (15)

3.3、配置参数 (16)

3.4、加载模板 (17)

3.5、异常处理 (19)

四、其它说明 (20)

4.1、变量 (20)

4.2、字符编码 (20)

4.3、多线程 (21)

4.5、Bean包裹 (21)

前言

FreeMarker官方参考文档总共有四份,它们分别是

●Designer's Guide(网上已有翻译,主要从FreeMarker的概念上介绍)

●Programmer's Guide(本文档所以翻译的部分,主要从框架的设计方面介绍)

●XML Processing Guide(对XML数据模型处理的介绍)

●Reference(FreeMarker的参考文档,语言使用介绍)

中文翻译之所以选择Programmer's Guide是因为个人觉得该部分对如何实现FreeMarker进行了比较深入的阐述。有助于读者很好的了解其运作机制,以及去理解其他模板引擎(如Velocity)的工作机理。

注:由于原文档部分内容直译可能难于被读者理解,所以有些地方采用意译为主,因此在翻译用词上难免可能会有出入,大家对翻译的内容有任何意见都可以给我直接发邮件告知motomagice@https://www.wendangku.net/doc/a313512733.html,

一、快速入门

1.1、创建配置实例

首先你需要创建一个Configuration(freemarker.template.Configuration)的实例,设置其中的某些属性。Configuration是存放FreeMarker的Application级别配置信息的一个重要地方。同时,它还负责创建及预解析模版(template)。

在应用系统的生命周期中(servlet)你只需要初始化创建一次Configure实例(因为它保存的是全局配置信息)

Configuration cfg=new Configuration();

//指定一个加载模版的数据源

//这里我设置模版的根目录

cfg.setDirectoryForTemplateLoading(new File("/where/you/store/templates")); //指定模版如何查看数据模型.这个话题是高级主题…

//你目前只需要知道这么用就可以了:

cfg.setObjectWrapper(new DefaultObjectWrapper());

你仅仅只需要这么一个配置就可以了。注意:如果你的系统中有多个独立的模块都要使用FreeMarker那么你就需要多个Configuration实例(也就是说你每一个组建都需要一个私有的配置)

1.2、创建数据模型(Data Model)

如果配置简单的数据模型,你可能只需要https://www.wendangku.net/doc/a313512733.html,ng和java.util以及一些Java Beans来构建FreeMarker的数据库模型。

?字符串使用https://www.wendangku.net/doc/a313512733.html,ng.String.

?数字使用https://www.wendangku.net/doc/a313512733.html,ng.Number

?布尔使用https://www.wendangku.net/doc/a313512733.html,ng.Boolean

?数组以及序列使用java.util.List

?Hashes(一种容器类型可以包含的多种基本类型)使用java.util.Map

?对于hashes类型的数据模型你也可以使用bean对象来存放,而数据项必须和bean 对象的属性项名称要一致。例如product有一个price属性,那么FreeMarker

则可以通过product.price来获取相应的值。

让我们来看一看怎么创建下面这个数据模型。

(root)

|

+-user="Big Joe"

|

+-latestProduct

|

+-url="products/greenmouse.html"

|

+-name="green mouse"

以下是创建该模型的java代码:

//创建一个hash类型作为数据模型的root

Map root=new HashMap();

//把字符串user放置到root中

root.put("user","Big Joe");

//再创建一个hash类型名字叫做latestProduct

Map latest=new HashMap();

//同样把它放置到root中

root.put("latestProduct",latest);

//放置url和name属性到latest

latest.put("url","products/greenmouse.html");

latest.put("name","green mouse");

对于数据模型中的latestProduct属性来说,你也可以使用普通Java Bean存储,但是bean必须要拥有url和name两个属性(也就是它有getURL()这些方法),对于FreeMarker模版来说两种定义数据库模型(Map,bean方式)的方式实质上是一样的。

1.3、获取模版(template)

模版对象一般就是指代freemarker.template.Template实例。通常你可以从一个Configuration实例中获取模版实例。你可以通过getTemplate这个方法来获得。

Template temp=cfg.getTemplate("test.ftl");

当你调用如上代码的时候,它将会创建一个与test.ftl对应的模版实例,也就是读取/where/you/store/templates/test.ftl路径下的文件然后解析(编译)。模版对象一般存储的是经过解析过的模版内容。

如果Configuration实例配置缓存Template实例策略的话,那么当你再次要获取test.ftl的时候,那么就可以从缓存中获得,而不会重新生成一个新的模版实例。

1.4、把模版与数据模型合并

我们都知道,数据模型+模版=输出,而我们一旦拥有数据模型(root)和一个模版(template)那么我们就可以把他们合并获得输出。

以上这个过程是通过template类的process方法来实现的,该方法需要两个参数一个是表示数据模型的root一个表示输出的Writer。它把解析过的文件输出到Writer上。简单起见,我把输出指定到了控制台(标准输出)

Writer out=new OutputStreamWriter(System.out);

temp.process(root,out);

out.flush();

由于Template实例是无状态的,一旦你获取了一个模版实例,那么你可以与不同的数据库模型多次合并。另外test.ftl文件是在Template实例被创建的时候就读取的,而不是等到调用process的时候才读取。

1.5、完整的代码

import freemarker.template.*;

import java.util.*;

import java.io.*;

public class Test{

public static void main(String[]args)throws Exception{

/*一般在应用的整个生命周期中你仅需要执行一下代码一次*/

/*创建一个合适的configuration*/

Configuration cfg=new Configuration();

cfg.setDirectoryForTemplateLoading(new

File("/where/you/store/templates"));

cfg.setObjectWrapper(new DefaultObjectWrapper());

/*而以下代码你通常会在一个应用生命周期中执行多次*/

/*获取或创建一个模版*/

Template temp=cfg.getTemplate("test.ftl");

/*创建一个数据模型Create a data model*/

Map root=new HashMap();

root.put("user","Big Joe");

Map latest=new HashMap();

root.put("latestProduct",latest);

latest.put("url","products/greenmouse.html");

latest.put("name","green mouse");

/*合并数据模型和模版*/

Writer out=new OutputStreamWriter(System.out);

temp.process(root,out);

out.flush();

}

}

注意:简单起见,以上代码是没有考虑异常处理的。

二、数据模型(Data Model)

2.1、基础类型

FreeMarker的数据模型(root状模型)可以使用标准的java类(Map,String等等)来表示。在其内部,FreeMarker使用的数据模型其实是――――――――――――――――实现了freemarker.template.TemplateModel接口的对象。但是你却可以使用诸如java collections对象作为你的数据模型,这是因为这些数据模型通常会被(FreeMarker)在内部转换成TemplateModel类型的对象。这种功能呢就叫做object wrapping。它可以透明地把任意对象转化成TemplateModel接口类型的实例。例如,它可以转换java.sql.ResultSet对象,也可以转变javax.servlet.ServletRequest对象,甚至可以转化XML文档表示的数据模型。

但是你在转换这些对象的时候,必须选取适合的包裹类(Wrapper,这些包裹类来实现普通对象到TemplateModel对象的转化工作,但你也可以自己定制一些Wrapper)。既然模版可以访问的数据模型必须都是转化成TemplateModel后的对象,所以你首先应该熟悉各个实现TemplateModel接口的子类。

TemplateModel主要有三个子类,每一个子类分别表示一种FreeMarker的基本类型,比如hashes类型用TemplateHashModel表示,sequence类型实现用TemplateSequenceModel来表示,numbers类型用TemplateNumberModel来表示,另外,自己也可以定制其他的数据模型的转化。

举个例子,如果你想转化java.sql.ResultSet为sequence,那么你只需要写一个实现了TemplateSequenceModel接口的对象,并且该对象可以读取ResultSet然后并把其转换成相应的TemplateModel,其实你要做的仅仅是生成一个ResultSet的包装类,并且继承TemplateSequenceModel接口。注意:一个类可以实现多个TemplateModel 类型的接口,这也就是为什么FreeMarker的变量会有多种的原因。

注意:在包freemarker.template中提供了以上这些接口的默认实现。例如,你要转换一个String类型那么你直接可以使用SimpleScalar,同样要转换一个Map类型你可以使用SimpleScalar,诸如此类等等。

如果你放置到root数据模型中的对象本身就是实现了TemplateModel接口的实例,那么Object Wrapper并不会去对该对象进行任何转换。

2.2、Scalar类型(单值对应的Data Model)

FreeMarker中的scalar类型可以表示如下的四种基本类型

?Boolean

?Number

?String

?Date

每种类型都是Template Type Model接口的实现,Type是以上类型名称的替换。这些接口只有一个方法getAs Type(),它返回以上java基本类型所表示的值(也就是boolean,Number,String类型的值)。

注意:由于历史版本的原因,String所对应的类型是TemplateScalarModel而不是TemplateStringModel。

以上接口的实现都可以在freemarker.template包中找到。但是boolean类型的值是用TemplateBooleanModel.TRUE和TemplateBooleanModel.FALSE来表示的。Scalars类型在FTL(FreeMarker模版)中都是不可变类。也就是该类型在赋值之后是不能改变的,除非生成一个新的实例。

数据类型中存在的难点

FreeMarker数据类型方面还有些许复杂,这是因为java API通常不区分java.util.Date-s(也就是说表示日期的,表示时间的都可以用Date类来存储)。为了能够用文本准确的表示Date的值,FreeMarker必须的准确的知道Date对象里面存放的到底是哪一种日期格式。不幸的是Java API只能区分数据库中定义的日期格式,因为据库语言会明确的使用date,time以及timestamp这三种类型来对日期进行存储,而相应的java.sql 包中有3种类型与之对应。

而在FreeMarker中时这么处理的,T emplateDateModel接口有getAsDate(),int getDateType()两个方法。你可以通过其getAsDate()获得一个java.util.Date对象,另外可以通过getDateType()再获得一个整数,而该整数用以指明究竟使用日期的哪种表达。该整型变量的值分别是DATE,TIME,DATETIME和UNKNOWN,并且都是常量.

那么什么又是UNKNOWN类型呢?在FreeMarker中当T emplateDateModel不知道存放在其中的日期是什么类型(date,time,timestamp)时将会用UNKNOW表示。

2.3、容器类型

在FreeMarker中一般有三种类型可以充当容器。

Hashes

Hashes类型是实现了TemplateHashModel接口的实例。TemplateHashModel容器类型包含两个方法get(String key)它可以根据给定的key返回容器包含的子变量boolean isEmpty()它可以判定容器是否包含有子变量。如果容器中不包含任何变量的话,那么get方法会返回null。

我们通常会使用实现该接口且名字叫SimpleHash的类来表示Hashes类型。其内部实现机制其实是使用java.util.Hash来存储子变量。你也可以通过该实例提供的方法来加入或者去除子变量。另外该类型的容器是不变类型(immutable)。

●sequences

sequences通常是实现了TemplateSequenceModel接口的java对象。该类型包含两个方法TemplateModel get(int index)和int size()。我们通常会使用实现该接口且名字叫SimpleSequence的类来表示sequence类型,其内部机制其实是使用java.util.List来存储子变量。SimpleSequence有新增子变量的方法。

●Collections

collections通常是实现了TemplateCollectionModel接口的java对象。该类型包含一个方法TemplateModelIterator iterator()。该接口类似java.util.Iterator。但是它返回的是TemplateModels而不是Object-s。异常的时会抛出TemplateModelException s。我们通常会使用实现该接口且名字叫SimpleCollection的类来表示collections类型。

2.4、方法变量

方法变量通常是实现了TemplateMethodModel接口的类,该接口有一个方法TemplateModel exec(java.util.List arguments)。当你使用方法表达式(method call expression)调用一个方法(exec)的时候,实际上是在执行exec。方法表达式的参数其实就是方法参数的变形。方法的返回值也就是方法表达式的返回值。

由于方法接口TemplateMethodModelEx继承自TemplateMethodModel接口,所以方法也可以当作变量一样被放置到root中。而显然方法接口是没有默认实现的,因为这些实现都要你亲自书写。

举个例子,有一个方法它返回第一个字符串首次出现在第二个字符串中的位置。如果在第二个字符串中找不到,那么则返回-1。

public class IndexOfMethod implements TemplateMethodModel{

public TemplateModel exec(List args)throws

TemplateModelException{

if(args.size()!=2){

throw new TemplateModelException("Wrong arguments");

}

return new SimpleNumber(

((String)args.get(1)).indexOf((String)args.get(0)));

}

}

如果你把方法变量按照如下的方式放置到root中

root.put("indexOf",new IndexOfMethod());}

那么你就可以按照如下的方式在模版中使用

<#assign x="something">

${indexOf("met",x)}

${indexOf("foo",x)}

以下是输出:

2

-1

如果你想访问运行时的FTL环境,对变量进行读写那么你需要获取Environment.getCurrentEnvironment().

2.5、转换器变量

转换器是实现TemplateTransformModel接口的类。你可以在freemarker.template.utility包下面找到一些有用的转换器实现。

扩展你自己的转换器

转换器接口有一个方法Writer getWriter(Writer out,Map args)。该方法将会转换标签之间的内容,首先把标签之间的内容读取到Writer对象中,再由Writer 对象对其中的内容施行转换处理,转换后的内容会再次存储到Writer中。调用flush方法后会把内容输出。不需要你去调用out.close(),当到达结束标签的时候close会自动被调用。

以下是一个转换标签之间内容为大写的例子

import java.io.*;

import java.util.*;

import freemarker.template.TemplateTransformModel;

class UpperCaseTransform implements TemplateTransformModel{

public Writer getWriter(Writer out,Map args){

return new UpperCaseWriter(out);

}

private class UpperCaseWriter extends Writer{

private Writer out;

UpperCaseWriter(Writer out){

this.out=out;

}

public void write(char[]cbuf,int off,int len)

throws IOException{

out.write(new String(cbuf,off,len).toUpperCase());

}

public void flush()throws IOException{

out.flush();

}

public void close(){

}

}

}

如果你把该变量放置到root数据模型中

root.put("upperCase",new UpperCaseTransform());

那么再模板文件中,你可以如下使用:

blah1

<@upperCase>

blah2

blah3

blah4

输出如下:

blah1

BLAH2

BLAH3

blah4

通常更好的做法是把一些可能公用的变量放置到Configure对象中当作为共享变量。

另外一点你需要认识到,如果转换器是有状态的话,那么它必须存储在Writer实例中,而不是TemplateTransformModel。那么TemplateTransformModel应当是无状态的,而且仅仅是创建Writer的工厂类。

考虑一下标签嵌套的情况和共享变量被多个线程同时访问的情况。FreeMarker是这么处理标签嵌套的,其返回的Writer可能是实现了一个freemarker.template.TransformControl接口。该接口的方法可以回调,那么就给了Writer对象一个机会是否执行嵌套在其中的标签(如<@myTransform>和之间还有标签)请参考API获得更加详细的介绍。

2.6、节点变量

节点变量是对树状数据结构中节点的表述。节点变量可以用来处理XML文档,但是也可以用来处理具有树状组织接口的数据结构。一个节点变量具有以下一些属性,这些属性都是由TemplateNodeModel接口提供的。

●基本属性:

TemplateSequenceModel getChildNodes():一个节点具有一系列的孩子节点(除了那些叶子节点外)而孩子节点属于节点变量。

TemplateNodeModel getParentNode():一个节点很显然有且只有一个父节点,除了根节点外。

●可选属性:(具体情况下,没有意义的属性一般返回null)

String getNodeName():节点的名字也就是宏的名字,当你使用rescurse和visit 指令的时候需要首先知道节点的名字。

String getNodeType():标识节点的类型element,text,comment

String getNamespaceURI():返回该节点的所处的名字空间(与FreeMarker的名字空间没有任何联系)

对于FreeMarker,直接使用内建的节点类型(node built-ins),大多数情况下,节点变量仅仅提供节点访问的基本功能,更详细的例子在“FreeMarker deals with XML”

2.7、对象包裹

你在API中可以看到,FreeMarker数据容器(root)可以放置任意的对象,而不一定就是实现了TemplateModel接口的对象。这是为什么呢?!因为FreeMarker提供的容器实例会在其内部把放置在其中的对象自动转换成实现了TemplateModel接口的对象。比如说,如果你放置一个String对象在容器中,它就会把String对象在内部自动转换成SimpleScalar。

至于何时发生转换,这是容器自身逻辑的问题。但是最晚也会在获取子变量的时候进行转换,因为获取子变量方法会返回TemplateModel对象而不是Object对象。例如,SimpleHash,SimpleSequence和SimpleCollection使用延迟转换策略(laziest strategy);它们会在第一次获取子变量的时候把其他类型的对象转换成TemplateModel 类型。

至于什么类型的对象可以被转换,以及具体转换成何种类型,一方面容器自身可以处理,另一方面也可以把它委托给ObjectWrapper实例去处理。ObjectWrapper是一个接口具有一个方法TemplateModel wrap(https://www.wendangku.net/doc/a313512733.html,ng.Object obj)。用户可以传递一个Object对象,它就会返回一个与之对应的TemplateModel对象,或者抛出异常。这些转换规则是写死在ObjectWrapper实现里面的。

FreeMarker提供的ObjectWrapper重要的实现有:

●ObjectWrapper.DEFAULT_WRAPPER:它可以把String转换成SimpleScalar,

Number转换成SimpleNumber,List和array转换成SimpleSequence,Map转换成SimpleHash,Boolean转换成T emplaeBooleanModel.TRUE/FALSE等等。(对于其他的类型对象的转换就要调用BEANS_WRAPPER)

●ObjectWrapper.BEANS_WRAPPER:它可以使用反射访问任意JavaBean的属性(后

面有单独的一章专门介绍该对象)

我们来看一个具体的例子,来观察Simple Xxx究竟是如何工作的,SimpleHash,SimpleSequence和SimpleCollection使用DEFAULT_WRAPPER来包裹子变量,所以以下这个例子是讲解的DEFAULT_WRAPPER处理原理。

Map map=new HashMap();

map.put("anotherString","blah");

map.put("anotherNumber",new Double(3.14));

List list=new ArrayList();

list.add("red");

list.add("green");

list.add("blue");

//将会使用default wrapper

SimpleHash root=new SimpleHash();

root.put("theString","wombat");

root.put("theNumber",new Integer(8));

root.put("theMap",map);

root.put("theList",list);

假如root是数据模型的根,那么以下的数据模型可以表述如下:

(root)

|

+-theString="wombat"

|

+-theNumber=8

|

+-theMap

||

|+-anotherString="blah"

||

|+-anotherNumber= 3.14

|

+-theList

|

+-(1st)="red"

|

+-(2nd)="green"

|

+-(3rd)="blue"

注意在theMap和theList中的对象也可被当作子变量访问,这是因为当你试图以theMap.anotherString访问数据的时候,SimpleHash会悄悄的把其替换成SimpleScalar对象。当你把任意的对象放置到root中时,DEFAULT_WRAPPER将会调用BEANS_WRAPPER 来对其进行转换。

SimpleHash root=new SimpleHash();

//放置一个简单的String对象

root.put("theString","wombat");

//放置任意的一个java objects:

root.put("theObject",new TestObject("green mouse", 1200));

假定T estObject类如下:

public class TestObject{

private String name;

private int price;

public TestObject(String name,int price){ https://www.wendangku.net/doc/a313512733.html,=name;

this.price=price;

}

//JavaBean属性

//注意这些属性你不能直接访问

//你必须给它们写getter方法

public String getName(){return name;}

public int getPrice(){return price;}

//A method

public double sin(double x){

return Math.sin(x);

}

}

以上所表示的数据模型是:

(root)

|

+-theString="wombat"

|

+-theObject

|

+-name="green mouse"

|

+-price=1200

|

+-number sin(number)

因此我们在模板中合并他们

${https://www.wendangku.net/doc/a313512733.html,}

${theObject.price}

${theObject.sin(123)}

输出结果是:

green mouse

1200

-0,45990349068959124

你或许在之前的手册中已经看到,我们是用java.util.HashMap作为数据模型的root,而不是SimpleHash或其它对象。这是因为当Template.process(...)处理的时候会自动依据Configuration级别指定的object_wrapper对其进行转换。

object_wrapper默认的配置是ObjectWrapper.DEFAULT_WRAPPER,如果你想改变包裹策略,如ObjectWrapper.BEANS_WRAPPER,你可以做以下修改:

cfg.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);

注意,你可以在这里设置任何实现了ObjectWrapper接口的对象,也就是说你可以定制你自己的包裹类。

三、配置(Configuration)

3.1、基础

Configuration是一个存放应用级别(application level)公共配置信息,以及模版(Template)可使用的全局共享变量的一个对象。同时它还负责模版(T emplate)实例的创建以及缓存。Configuration实际上是freemarker.template.Configuration对象的实例,使用其构造函数创建。通常应用使用一个共享的单实例Configuration对象。

Configuration对象可被T emplate对象的方法使用,每一个模版实例都关联与一个Configuration实例,它是通过T emplate的构造函数被关联进去的,通常是你使用这个方法来Configuration.getTemplate获得模版对象的。

3.2、共享变量

共享变量是那些定义给所有模版(Template)使用的变量。你可以通过configuration 对象的setSharedVariable方法来添加共享变量。

Configuration cfg=new Configuration();

...

cfg.setSharedVariable("to_upper",new UpperCaseTransform());

cfg.setSharedVariable("company","FooInc.");

ObjectWrapper.DEFAULT_WRAPPER

所有与该configuration对象关联的模版实例都就可以通过获得to_upper转换器,company来获得字符串,因此你不需要再一次次的往root中添加这些变量了。如果你往root添加同名的变量,那么你新添加的变量将会覆盖之前的共享变量。

警告!

如果configuration对象被多线程调用,那么不要使用TemplateModel实现类作为共享变量,因为他们是非线程安全的。例如基于servlet的web站点就是这种情况。

Configuration对象初始化时已经包含一些共享转换器变量:

名字类

capture_output freemarker.template.utility.CaptureOutput compress freemarker.template.utility.StandardCompress html_escape freemarker.template.utility.HtmlEscape

normalize_newlines freemarker.template.utility.NormalizeNewlines xml_escape freemarker.template.utility.XmlEscape

3.3、配置参数

配置参数是那些可以影响FreeMarker运行行为的那些命名参数。例如locale, number_format

配置参数存储在Configuration实例中,它可以被模版实例(T emplate)修改。例如,你在Configuration中设置了locale等于"en_US",那么所有的模版对象都会使用,"en_US"除非你在单个模版实例中利用setLocale方法修改了默认配置。因此configuration设置的参数可以当作是默认参数,它可以被T emplate一级设置的参数覆盖,而它们两者设置的参数信息又可以被环境中设置的参数所覆盖(也就是模版文件指令设置的)如下:

${1.2}

<#setting locale="en_US">

${1.2}

这种调用方式你可以想象成3个层(配置对象层,模版层,运行环境层)下面表格中显示了每一层对于参数的设置:

Setting A Setting

B

Setting

C

Setting

D

Setting

E

Setting

F

Layer3:Runtime

environment

1--1--

Layer2:Template22--2-

Layer1:Configuration3333--

那么配置参数的最终结果分别是:A=1,B=2,C=3,D=1,E=2.而F参数很可能就是null。

如果要查询可设置的参数列表,你可以查阅FreeMarker API文档的以下两个部分:freemarker.core.Configurable.setSetting(String,String):

所有层的配置

freemarker.template.Configuration.setSetting(String,String):

Coniguration层的配置

3.4、加载模板

模版加载器

模版加载器是基于抽象路径("index.ftl"或"products/catalog.ftl")

加载原始数据的那些对象。而究竟加载何种资源(目录中的文件数据还是数据库中的数据)

取决于具体的加载器实现。当你调用cfg.getTemplate时,FreeMarker将会询问你

之前配置给Configuration对象的模版加载器,有该模版加载器负责文件的载入。

内建的模版加载器

你可以用以下三个方法来设置模版加载的三种方式

void setDirectoryForTemplateLoading(File dir);

或者

void setClassForTemplateLoading(Class cl,String prefix);

或者

void setServletContextForTemplateLoading(Object servletContext,String path);

以上第一种方式显示的指定了一个文件系统中的目录,FreeMarker将会在此目录记载

模版,不用说,此目录必须存在,否在会抛出异常。

第二种方式以一个Class作为一个输入参数,当你想使用ClassLoader的方式来加

载模版的时候,你就可以使用这种方式,这种方式将会调用来寻找模版文件,同时这种模版

加载的方式要比前一种稳定一些尤其是在生产系统中。你可以很容易的把资源文件,以及图

标等打包到.jar文件中。

第三种方式把web应用的上下文以及基路径(相对与WEN-INF的父路进来说)作为

参数。该种方式的模版加载器将会从web应用上下文种加载模版。

从多个位置加载模版

如果你想从多个位置加载模版的话,你可以分别创建与不同位置对应的单个模版加载器,然后把它们包裹到一个名叫MultiTemplateLoader模版加载器中,最终通过方法setTemplateLoader(TemplateLoader loader)把其设置给Configuration对象,以下有一个从两个不同位置加载模版的例子:

import freemarker.cache.*;//template loaders live in this

package

...

FileTemplateLoader ftl1=new FileTemplateLoader(new

File("/tmp/templates"));

FileTemplateLoader ftl2=new FileTemplateLoader(new

File("/usr/data/templates"));

ClassTemplateLoader ctl=new ClassTemplateLoader(getClass(), "");

TemplateLoader[]loaders=new TemplateLoader[]{ftl1,ftl2, ctl};

MultiTemplateLoader mtl=new MultiTemplateLoader(loaders);

cfg.setTemplateLoader(mtl);

FreeMarker将会首先在路径/tmp/templates中搜索模版文件,如果没有找到那么回到路径/usr/data/templates中搜索,如果还没有找到,那么则会尝试用class-loader 的方式加载。

从其他资源中获取模版文件

如果在这些内建的模版加载器中没有一个符合你的要求,那么你可以自己定制一个模版加载器,只需要实现freemarker.cache.TemplateLoader接口就可以了,然后通过方法setTemplateLoader(TemplateLoader loader)把其传递给Configuration对象。

缓存模版

FreeMarker缓存模版的意思就是,当你通过getTemplate方法获取一个模版的时候,FreeMarker不仅会返回一个Template对象,而且会缓存该对象,当你下一次以相同的路径请求模版的时候,它就会返回缓存中的模版对象。如果你改变了模版文件,那么当你下一次获取模版的时候,FreeMarker会自动重新加载,重新解析模版。虽然如此,但是如果直接判断一个文件是否修改过是一个耗时的操作,那么FreeMarker在Configuration对象级别提供了一个配置参数“update delay”。该参数的意思是FreeMarker多长时间去判断一次模版的版本,默认设置是5秒钟,也就是每个5秒就会判断模版是否经过修改,如果你想实时的判断,那么设置该参数为0。另外一点需要注意,并不是所有的加载器都支持这种

判断方式,举例来说基于class-loader的模版加载器就不会发现你修改过模版文件。

对于删除缓存中的模版FreeMarker是这么做的,你可以使用Configuration对象方法clearTemplateCache以手工的方式清楚缓存中的模版对象。而实际上缓存部分可以作为一个组建加入到FreeMarker中(也就是它可以使用第三方缓存方案)你可以通过设置cache_storage这个参数来实现。对大多数开发者来FreeMarker自带的freemarker.cache.MruCacheStorage实现已经足够了。这个缓存使用2个级别的Most Recently Used(最近最多用)策略。在第一个级别,所有的缓存条目都是使用强引用(strongly referenced:条目并不会被JVM所清楚,与其相对的弱引用softly reference)直到达到最大时间,那些最近最少使用的条目就会被迁移到二级缓存。在这个级别条目都是使用弱引用直到达到过期。若引用与强引用的区域的大小是可以在构造函数中设置的,例如你想把强引用区域设置为20,弱引用区域设置为250,那你可以使用以下代码:

cfg.setCacheStorage(new freemarker.cache.MruCacheStorage(20,250))由于MruCacheStorage是默认的缓存实现,那么你也可以这样设置:

cfg.setSetting(Configuration.CACHE_STORAGE_KEY,"strong:20,soft:250");

当你创建一个新的Configuration时,其默认使用MruCacheStorage缓存实现且默认的值maxStrongSize等于0,maxSoftSize等于Integer.MAX_VALUE(也就是理论最大值)。但是对于高负荷的系统来说,我们建议maxStrongSize设置成一个非0的数值,不然会导致频繁的重新加载,重新解析模版。

3.5、异常处理

可能产生的异常

FreeMarker产生的异常一般可归以下几类:

●FreeMarker初始化阶段产生的异常:通常在你的应用中仅需要初始化

FreeMarker一次,而当在这个时间段类产生的异常就叫做初始化异常。

●加载解析模版期的异常:当你通过Configuration.getTemplate()

方法获取模版的时候(如果模版之前没有被缓存),将会产生两类异常。

IOException:由于模版没有找到,或在读取模版的时候发生其他的

IO异常,比如你没有读取该文件的权限等等。

freemarker.core.ParseException由于模版文件的语法使用

不正确。

●执行期间的异常。:当你调用Template.process(...)方法的时候,会

抛出两类异常。

IOException往输出写数据时候发生的错误。

freemarker.template.TemplatException其他运行期产生

的异常。比如一个最常见的错误就是模版引用了一个不存在的变量。

异常的定制

由于客户一般不会直接使用该章节的内容去进行FreeMarker的配置(FreeMarker官方也不赞成自己定义异常),所以以下的内容将略去。

四、其它说明

4.1、变量

在这一章中主要介绍模版是怎么样访问变量的,以及如何存储变量。

当你调用Template.process方法时,FreeMarker内部会创建一个Environment对象直到process方法调用结束。这个变量存放着FreeMarker运行期的状态以及经由assign,macro,local global等创建的变量。当你需要读取某个变量的时候,FreeMarker就会按照次序去查找,如果找到匹配的变量,那么就会返回。

1、在Environment对象中:

1、循环变量是经由list指令创建的。

2、在宏变量中可以创建local变量。

3、在当前的命名空间中,你可以使用assign来给变量取值。

4、使用global指令创建的变量,可以像使用数据模型中的数据一样在所有的命令

空间都可以使用。

2、在数据库模型对象中:

这其中的变量是通过process方法被传递进去的。

3、在共享变量中:

这些是设置在Configuration对象中的变量。

4.2、字符编码

像大多数java应用一样,FreeMarker也是使用”UNICODE”编码,虽然如此,但是有些情况下还是要面对字符编码问题(charsets),因为它必须与外界使用的多种多样的字符集进行交互。

输入的字符编码

当FreeMarker加载模版的时候,它必须得知道被加载文件的字符编码,你可以使用encoding设置来指定编码。这个设置仅仅在你调用Configuration对象的getT emplate方法的时候起作用。对于eccoding这个参数提供了getter以及setter方法,当你使用getter 方法获取编码的时候,它会基于你传递的locale来查找一张表(这张表是由locale,encoding 对应组成的)来确定具体的encoding,如果找不到的话,将会使用默认的encoding(默认的encoding通常用setDefaultEncoding来设置)

同时你也可以使用ftl指令来指定页面的编码方式。

总之,把你所有的页面编码设置成为UTF-8将会是最好的办法。

输出字符编码

原则上FreeMarker将不对输出字符编码进行处理,因为输出是通过对象来实现的。因此这部分的翻译也就不在赘述,最好的办法依然是设置所有的字符编码为UTF-8。

Spring2.5、Struts2.1、Hibernate3.2、sitemesh、freemarker整合开发常见问题及解决方案

1.在搭建SSH开发平台的时候,由MyEclipse自动导入的包存在一些冲突,主要有 (1) asm.jar与asm-2.2.3.jar asm-2.2.3是spring所依赖,而asm.jar是hibernate依赖的,应该删除asm-2.2.3.jar这个包 (2). commons-logging-1.0.4.jar与commons-logging-api-1.1.jar 这两个包中commons-logging-1.0.4.jar是spring和hibernate以及struts都要用的包,但是struts2.1以上的版本还需要commons-logging-api-1.1.jar,其实这两个包几乎一样,commons-logging-api-1.1.jar版本较新而已。 (3)异常 严重: Exception starting filter struts2 https://www.wendangku.net/doc/a313512733.html,ng.NullPointerException at com.opensymphony.xwork2.spring.SpringObjectFactory.getClassInstance(SpringObjectF actory.java:203) ... 可能的原因是spring的默认配置文件applicationContext.xml改了名,或者没有放在classpath的根路径下面,并且没有在web.xml文件中配置spring的监听器,解决办法在web.xml中添加

org.springframework.web.context.ContextLoaderListener (4)异常 严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/applicationContext.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml] 可能的原因是虽然配置了spring的监听器,但是没有在web.xml中配置contextConfigLocation来指定spring配置文件列表及相应的具体路径。解决的办法是在web.xml文件中添加,例如: contextConfigLocation /WEB-INF/csdn-spring*.xml (5)异常 org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is org.hibernate.exception.GenericJDBCException: Cannot open connection 可能的原因是缺少相应的JDBC驱动包,请把驱动包拷贝到/WEB-INF/lib下面,或者是数据源的配置有问题,例如用户名、者密码或者URL错误。

AERMOD中文参考手册

大气环境影响预测系统使用者参考手册 一、简介 大气环境影响预测系统是一款由浙江省环科院环评二所任剑波工程师开发的预测大气环境影响的界面化软件,其主要功能是对各类型污染源在不同条件下排放污染物进行模拟,计算其所造成的污染物地面浓度分布,用量化的方法预测污染源对大气环境的影响。 大气环境影响预测系统的核心模块采用《环境影响评价技术导则-大气环境》(HJ2.2-2008)推荐的美国Environmental Protection Agency的AERMOD预测模型和SCREEN3估算模式。AERMOD是一个稳态羽烟扩散模式,可基于大气边界层数据特征模拟点源、面源、体源等排放出的污染物在短期(小时平均、日平均)、长期(年平均)的浓度分布,适用于农村或城市地区、简单或复杂地形。AERMOD考虑了建筑物尾流的影响,即烟羽下洗。模式使用每小时连续预处理气象数据模拟大于等于1小时平均时间的浓度分布。AERMOD包括两个预处理模式,即AERMET气象预处理和AERMAP地形预处理模式。AERMOD适用于评价范围小于等于50km的一级、二级评价项目。 估算模式SCREEN3 是一个单源高斯烟羽模式,可计算点源、火炬源、面源和体源的最大地面浓度,以及下洗和岸边熏烟等特殊条件下的最大地面浓度。估算模式中嵌入了多种预设的气象组合条件,包括一些最不利的气象条件,在某个地区有可能发生,也有可能没有此种不利气象条件。所以经估算模式计算出的是某一污染源对环境空气质量的最大影响程度和影响范围的保守的计算结果。 二、操作界面介绍 大气环境影响预测系统界面非常友好,继承了windows操作系统软件的特点。其最上方为命令菜单;在命令菜单的下方是快捷工具栏;左侧区域为目标管理窗口,可以更加方便的进行输入和管理预测模型所需的各类参数数据;右侧区域为工作区,用户可在此直接操作,例如添加底图,标明污染源、计算区域和预测点位置等。 1.菜单栏 本软件操作界面中的菜单栏分为文件、显示、运行、计算结果、工具和关于六项。各命令菜单包含的内容如下: ·文件 新建; 打开; 保存; 另存为; 保存inp文件; 打开示例文件; 退出 ·显示 污染源; 预测点; 计算网格; 建筑物; 显示标尺;

Spring中文开发详细手册

Spring开发教程 Spring教程 (1) Spring框架概述 (2) Spring是什么? (2) Spring的历史 (3) Spring的使命(Mission Statement) (3) Spring受到的批判 (3) Spring包含的模块 (4) 总结 (5) Spring的IoC容器 (6) 用户注册的例子 (6) 面向接口编程 (7) (用户持久化类)重构第一步——面向接口编程 (8) 重构第二步——工厂(Factory)模式 (9) 重构第三步——工厂(Factory)模式的改进 (9) 重构第四步-IoC容器 (10) 控制反转(IoC)/依赖注入(DI) (10) 什么是控制反转/依赖注入? (10) 依赖注入的三种实现形式 (11) BeanFactory (13) BeanFactory管理Bean(组件)的生命周期 (14) Bean的定义 (15) Bean的之前初始化 (19) Bean的准备就绪(Ready)状态 (21) Bean的销毁 (21) ApplicationContext (21) Spring的AOP框架 (21) Spring的数据层访问 (21) Spring的声明式事务 (21) Spring对其它企业应用支持 (22)

名词解释 容器: 框架: 框架 容器 组件: 服务: Spring框架概述 主要内容:介绍Spring的历史,Spring的概论和它的体系结构,重点阐述它在J2EE中扮演的角色。 目的:让学员全面的了解Spring框架,知道Spring框架所提供的功能,并能将Spring 框架和其它框架(WebWork/Struts、hibernate)区分开来。 Spring是什么? Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring 的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。 ?目的:解决企业应用开发的复杂性 ?功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能 ?范围:任何Java应用 简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。 ■轻量——从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布。并且Spring所需的处理开销也是微不足道的。此外,Spring是非侵入式的:典型地,Spring应用中的对象不依赖于Spring的特定类。 ■控制反转——Spring通过一种称作控制反转(IoC)的技术促进了松耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。 ■面向切面——Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务()管理)进行内聚性的开发。应用对象只实

ftl编辑器(freemarker)的使用和说明

一、准备工作 1.1 下载文件 可以从https://www.wendangku.net/doc/a313512733.html,/站点下载最新的freemarker.jar包(目前最新版本是2.3.18)与eclipse插件(最新版本是0.9.14)。 1.2 安装eclipse插件 将下载来的eclipse插件解压缩到本地磁盘,更改hudson.freemarker_ide_0.9.14文件夹中的freemarker-2.3.6.jar文件更改成最新版本的freemarker-2.3.18.jar,并且将META-INF/MANIFEST.MF文件中的Bundle-ClassPath属性值修改为freemarker-2.3.18.jar。最后将hudson.freemarker_ide_0.9.14放到eclipse的plugins目录中,完成eclipse 插件的安装。 1.3 freemarker文档下载 从https://www.wendangku.net/doc/a313512733.html,/官方网站中下载帮助文档(也有中文的手册) 二、freemarker的使用 2.1 简介 2.1.1 FTL tag标签 由于freemarker tag标签是属于freemarker的指令,它们仅仅是freemarker 处理过程中的信息,而不会输出到页面上,所以它们与html标签有一些区别。这些标签都是以#号开头,如<#import "/public/work_public.ftl" as public>。但用户自定义的标签是以@符号开头,如在freemarker中使用struts标签:<@s.if test="results!=null&&results.size()!=0"> 注意FTL标签不可以在其他FTL标签和插值中使用(注释可以在FTL标签和插值中使用,因为它在解析时,整个注释都将抛弃,不会影响具体代码),如下面这样就是一个错误的写法: <#if <#include 'foo'>='bar'>... 2.1.2 注释 freemarker的文档注释与html相似,但它是以<#--和-->来分割的。任何介于这两个分隔符(包含分隔符本身)之间内容会被freemarker忽略,就不会输出出来了。其他任何不是FTL 标签,插值或注释的内容将被视为静态文本,这些东西就不会被freemarker所解析,会被按照原样输出出来。

freemarker语法

语法 FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主要由如下4个部分组成: 1. 文本:直接输出的部分 2. 注释:<#-- ... -->格式部分,不会输出 3. 插值:即${...}或#{...}格式的部分,将使用数据模型中的部分替代输出 4. FTL指令:FreeMarker指定,和HTML标记类似,名字前加#予以区分,不会输出 1. FTL指令规则 在FreeMarker中,使用FTL标签来使用指令,FreeMarker有3种FTL标签,这和HTML标签是完全类似的. 1.开始标签:<#directivename parameter> 2.结束标签: 3.空标签:<#directivename parameter/> 实际上,使用标签时前面的符号#也可能变成@,如果该指令是一个用户指令而不是系统内建指令时,应将#符号改成@符号. 使用FTL标签时, 应该有正确的嵌套,而不是交叉使用,这和XML标签的用法完全一样.如果全用不存在的指令,FreeMarker不会使用模板输出,而是产生一个错误消息.FreeMarker会忽略FTL标签中的空白字符.值得注意的是< , /> 和指令之间不允许有空白字符. 2. 插值规则 FreeMarker的插值有如下两种类型:1,通用插值${expr};2,数字格式化插值:#{expr}或#{expr;format} 2.1 通用插值 对于通用插值,又可以分为以下4种情况: 1. 插值结果为字符串值:直接输出表达式结果 2. 插值结果为数字值:根据默认格式(由#setting指令设置)将表达式结果转换成文本输 出.可以使用内建的字符串函数格式化单个插值,如下面的例子: <#settion number_format="currency"/> <#assign answer=42/> ${answer} ${answer?string} <#-- the same as ${answer} --> ${answer?string.number} ${answer?string.currency} ${answer?string.percent}

TRSMASv5.0置标使用手册

媒资管理系统Array TRS Media Asset System 置标使用手册 北京拓尔思信息技术股份有限公司 Beijing TRS Information Technology Co., Ltd.

版权说明 本手册由北京拓尔思信息技术股份有限公司(以下简称TRS公司)出版,版权属TRS公司所有。未经出版者正式书面许可,不得以任何方式复制本文档的部分或全部内容。 ?北京拓尔思信息技术股份有限公司版权所有。保留所有权利。 是北京拓尔思信息技术股份有限公司的注册商标。

关于本手册 置标使用手册介绍了MAS5.0中置标组件的基本使用,并提供了相关实例,方便理解置标模板的编写以及使用,进而完成前台页面定制功能。 读者对象 本手册的读者为TRSMAS的使用者。使用者应具备以下基础知识: ●熟悉Windows或Linux操作系统; ●熟悉Oracle、MySQL、Microsoft SQL Server; ●熟悉HTML基本知识 ●掌握基本的编程技巧 用户反馈 TRS公司感谢您使用TRS 产品。如果您发现本手册中有错误或者产品运行不正确,或者您对本手册有任何意见和建议,请及时与TRS公司联系。您的意见将是我们做版本修订时的重要依据

目录 第1章概述 (1) 第2章使用说明 (2) 2.1快速入门 (2) 2.2管理台使用 (3) 2.2.1 站点(Site) (3) 2.2.2 映射(Pagelink) (3) 2.2.3 模板(Template) (4) 2.3站点规划 (5) 2.3.1 站点规划 (5) 2.3.2 映射规划 (5) 2.4模板规划 (6) 2.4.1 将主页面划分成块 (6) 2.4.2 使用TRS_PAGELET填充各块 (7) 2.4.3 编写小模板 (9) 2.4.4 完善TRS_PAGELET的属性 (9) 2.4.5 切换模板展示方式 (11) 2.5获取相关模板实例 (13) 第3章置标详细参考 (14) 3.1置标规范实例 (14) 3.1.1 OBJECTS - PROPERTY(一组数据) (14) 3.1.2 OBJECT - PROPERTY (一个数据) (15) 3.1.3 OBJECTS – (PROPERTY + PAGE)(组数据分页展示) (15) 3.1.4 OBJECTS –OBJECT –PROPERTY (折行显示列表数据) (16) 3.1.5 OBJECTS-(PROPERTY+OBJECTS-PROPERTY)(树状) (17) 3.1.6 OBJECTS-SWITCH-PROPERTY(条件显示) (18) 3.1.7 LINKGROUP – LINK链接着色 (19) 3.2置标详细说明 (19) 3.2.1 TRS_OBJECTS置标 (19) 3.2.2 TRS_OBJECT置标 (20) 3.2.3 TRS_PROPERTY置标 (21) 3.2.4 TRS_PAGE置标 (23) 3.2.5 TRS_SWITCH置标 (24) 3.2.6 TRS_LOOP置标 (25) 3.2.7 TRS_LINKGROUP置标 (26) 3.2.8 TRS_LINK置标 (28) 3.2.9 TRS_PAGELET置标 (28)

freemarker中文手册文档

FreeMarker FreeMarker Java FreeMarker HTML Web MVC FreeMarker Java FreeMarker FreeMarker Web Web FreeMarker HTTP Servlet FreeMarker Web FreeMarker Model2 Struts JSP FreeMarker 1

HTML XML RTF Java Servlet Email Web Web 2 include if/elseif/else HTML 3 FreeMarker Java Java JavaBean XML SQL

4 Web Web HTML Model2 Web JSP JSP MVC 5 UNICODE US 6 XML <#recurse> <#visit> 2.3 XML XML FreeMarker (1)

1 1 + = FreeMarker —— HTML Web Web HTML FreeMarker Welcome!

Welcome ${user}!

Our latest product: ${https://www.wendangku.net/doc/a313512733.html,}!

HTML ${…} FreeMarker FreeMarker Template user latestProduct.url https://www.wendangku.net/doc/a313512733.html, data model (root) | +- user = "Big Joe" | +- latestProduct | +- url = "products/greenmouse.html" | +- name = "green mouse" latestProduct user url name url name latestProduct

freemarkermacro(宏)的使用

FreeMarker macro(宏)的使用.txt14热情是一种巨大的力量,从心灵内部迸发而出,激励我们发挥出无穷的智慧和活力;热情是一根强大的支柱,无论面临怎样的困境,总能催生我们乐观的斗志和顽强的毅力……没有热情,生命的天空就没的色彩。FreeMarker macro(宏)的使用 有人说用freemarker,但没有用到它的宏(macro),就=没有真正用过freemarker。说的就是宏是freemarker的一大特色。 宏的定义可以查看相关的文档,里面介绍得很清楚,下面来看看它的一个用法(javaeye 帖子里有讨论)。 /WEB-INF/template/common/: <#macro html title> ${title} <#nested/> 然后在里定义: auto_import=/WEB-INF/template/common/ as c 然后其他的ftl文件就可以使用它了 : title="OA"> 你的内容 > 如果不在里定义,可以在每个文件里包含这个ftl: <#import "/WEB-INF/template/common/" as c> 不同的场合有不同的运用。使用得好的话,将会大大节省你的开发时间。 macro, nested, return 语法

freemarker中文API手册

FreeMarker概述 ●FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java 编写 ●FreeMarker被设计用来生成HTML Web页面,特别是基于MVC模式的应用程序●虽然FreeMarker具有一些编程的能力,但通常由Java程序准备要显示的数据,由 FreeMarker生成页面,通过模板显示准备的数据(如下图) ●FreeMarker不是一个Web应用框架,而适合作为Web应用框架一个组件 ●FreeMarker与容器无关,因为它并不知道HTTP或Servlet;FreeMarker同样可以应 用于非Web应用程序环境 ●FreeMarker更适合作为Model2框架(如Struts)的视图组件,你也可以在模板中使 用JSP标记库 ●FreeMarker是免费的 1、通用目标 ●能够生成各种文本:HTML、XML、RTF、Java源代码等等 ●易于嵌入到你的产品中:轻量级;不需要Servlet环境 ●插件式模板载入器:可以从任何源载入模板,如本地文件、数据库等等 ●你可以按你所需生成文本:保存到本地文件;作为Email发送;从Web应用程序发送 它返回给Web浏览器 2、强大的模板语言 ●所有常用的指令:include、if/elseif/else、循环结构 ●在模板中创建和改变变量 ●几乎在任何地方都可以使用复杂表达式来指定值 ●命名的宏,可以具有位置参数和嵌套内容 ●名字空间有助于建立和维护可重用的宏库,或者将一个大工程分成模块,而不必担心 名字冲突 ●输出转换块:在嵌套模板片段生成输出时,转换HTML转义、压缩、语法高亮等等; 你可以定义自己的转换 3、通用数据模型 ●FreeMarker不是直接反射到Java对象,Java对象通过插件式对象封装,以变量方式在

Freemarker教程 中文版

FreeMarker2.3.10 ―Programmer's Guide(中文版)

前言 (3) 一、快速入门 (4) 1.1、创建配置实例 (4) 1.2、创建数据模型(Data Model) (4) 1.3、获取模版(template) (5) 1.4、把模版与数据模型合并 (6) 1.5、完整的代码 (6) 二、数据模型(Data Model) (7) 2.1、基础类型 (7) 2.2、Scalar类型(单值对应的Data Model) (8) 2.3、容器类型 (8) 2.4、方法变量 (9) 2.5、转换器变量 (10) 2.6、节点变量 (12) 2.7、对象包裹 (12) 三、配置(Configuration) (15) 3.1、基础 (15) 3.2、共享变量 (15) 3.3、配置参数 (16) 3.4、加载模板 (17) 3.5、异常处理 (19) 四、其它说明 (20) 4.1、变量 (20) 4.2、字符编码 (20) 4.3、多线程 (21) 4.5、Bean包裹 (21)

前言 FreeMarker官方参考文档总共有四份,它们分别是 ●Designer's Guide(网上已有翻译,主要从FreeMarker的概念上介绍) ●Programmer's Guide(本文档所以翻译的部分,主要从框架的设计方面介绍) ●XML Processing Guide(对XML数据模型处理的介绍) ●Reference(FreeMarker的参考文档,语言使用介绍) 中文翻译之所以选择Programmer's Guide是因为个人觉得该部分对如何实现FreeMarker进行了比较深入的阐述。有助于读者很好的了解其运作机制,以及去理解其他模板引擎(如Velocity)的工作机理。 注:由于原文档部分内容直译可能难于被读者理解,所以有些地方采用意译为主,因此在翻译用词上难免可能会有出入,大家对翻译的内容有任何意见都可以给我直接发邮件告知motomagice@https://www.wendangku.net/doc/a313512733.html,

freemarker中文手册

FreeMarker概述

FreeMarker概述 ●FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java 编写 ●FreeMarker被设计用来生成HTML Web页面,特别是基于MVC模式的应用程序●虽然FreeMarker具有一些编程的能力,但通常由Java程序准备要显示的数据,由 FreeMarker生成页面,通过模板显示准备的数据(如下图) ●FreeMarker不是一个W eb应用框架,而适合作为W eb应用框架一个组件 ●FreeMarker与容器无关,因为它并不知道HTTP或Servlet;FreeMarker同样可以应 用于非W eb应用程序环境 ●FreeMarker更适合作为Model2框架(如Struts)的视图组件,你也可以在模板中使 用JSP标记库 ●FreeMarker是免费的 1、通用目标 ●能够生成各种文本:HTML、XML、RTF、Java源代码等等 ●易于嵌入到你的产品中:轻量级;不需要Servlet环境 ●插件式模板载入器:可以从任何源载入模板,如本地文件、数据库等等 ●你可以按你所需生成文本:保存到本地文件;作为Email发送;从Web应用程序发送 它返回给Web浏览器 2、强大的模板语言 ●所有常用的指令:include、if/elseif/else、循环结构 ●在模板中创建和改变变量 ●几乎在任何地方都可以使用复杂表达式来指定值 ●命名的宏,可以具有位置参数和嵌套内容 ●名字空间有助于建立和维护可重用的宏库,或者将一个大工程分成模块,而不必担心 名字冲突 ●输出转换块:在嵌套模板片段生成输出时,转换HTML转义、压缩、语法高亮等等; 你可以定义自己的转换 3、通用数据模型 ●FreeMarker不是直接反射到Java对象,Java对象通过插件式对象封装,以变量方式在

SSD1289中文手册

SSD1289

1 概述 SSD1289是集成RAM、电源电路、门驱动器、驱动源于一体的TFTLCD驱动控制器。它最大可驱动分辨率为240×320的26.2万色RGB非晶TFT面板。 SSD1289同样集成了控制功能。其包括172800字节的图形显示数据区。因此,通过兼容的并行或串行接口,它可以与像6800及8080系列的8-/9-/16-/18位通用微控制器接口,将数据写入图形显示数据区。另外,集成辅助的18-/16-/6位的视频接口用于动画图像的显示。 SSD1289嵌入了DC-DC变压器和电压转换器,用于提供芯片驱动所有外部底层元件所必需的电压。芯片包含的一个通用电压发生电路用于驱动TFT显示器的反电极。另外还有一个整合的伽马控制电路,用于配合软指令以提供最大的灵活性和最佳的显示效果。 DS1289工作的最低电压能低到1.16V,同时提供不同的节电模式。它适用于任何需要长时间运行的,用便携式电池驱动的紧凑型设备。 2 特点 ●工作电压:V DD = 1.65V-1.95V (不规则的逻辑输入) = 1.4V-3.6V (规则的逻辑输入) V DDIO = 2.5V-3.6V (内部模拟电路的电源供应) V CI ●最大的门驱动输出电压:30Vp-p ●驱动源输出电压:0-5V ●低电流睡眠模式和8-color节能显示模式 ●显示尺寸:240RGB×320 ●显示颜色支持:26.2万色RGB非晶TFT面板 ●8/9/16/18位的6800系列/8080系列的并行接口和串行接口 ●支持动画显示的18位RGB接口(VSYNC, HSYNC, DOTCLK, DEN, and D0-17)●片上172800字节的图形显示数据区 ●RAM写同步功能 ●支持线性和帧转换 ●软件可选中心滚屏、顶部滚屏、底部滚屏和全部滚屏。 ●Source and Gate scan direction control ●片内电平发生器 ●片内电压转换器高达6x/-6x ●可编程的伽马矫正曲线 ●对VCOM标准的稳定存储 ●可编程的公共电极电压幅度和一般结构的Cs水平 ●支持Cs的门结构 ●COG包可用 3 订购信息 4 结构图

FreeMarker使用介绍

1、快速入门
(1)模板+数据模型=输出 模板+数据模型= FreeMarker 基于设计者和程序员是具有不同专业技能的不同个体的观念 他们是分工劳动的:设计者专注于表示——创建 HTML 文件、图片、Web 页面的其它 可视化方面;程序员创建系统,生成设计页面要显示的数据 经常会遇到的问题是:在 Web 页面(或其它类型的文档)中显示的信息在设计页面 时是无效的,是基于动态数据的 在这里,你可以在 HTML(或其它要输出的文本)中加入一些特定指令,FreeMarker 会在输出页面给最终用户时,用适当的数据替代这些代码 下面是一个例子:
Welcome!

Welcome${user}!

Our latest product: ${https://www.wendangku.net/doc/a313512733.html,}!
这个例子是在简单的 HTML 中加入了一些由${…} ${…}包围的特定代码,这些特定代码是 ${…} FreeMarker 的指令,而包含 FreeMarker 的指令的文件就称为模板(Template) 至于 user、latestProduct.url 和 https://www.wendangku.net/doc/a313512733.html, 来自于数据模型(data model) 数据模型由程序员编程来创建,向模板提供变化的信息,这些信息来自于数据库、 文件,甚至于在程序中直接生成 模板设计者不关心数据从那儿来,只知道使用已经建立的数据模型 下面是一个可能的数据模型:
(root) | +- user = "Big Joe" | +- latestProduct | +- url = "products/greenmouse.html" |

thymeleaf 中文文档

Thymeleaf的首个稳定版(1.0.0版)已经于上月17日发布了。Thymeleaf是个XML/XHTML/HTML5模板引擎,可以用于Web与非Web应用。它是个开源的Java库,基于Apache License 2.0许可,由Daniel Fernández创建,Daniel Fernández还是Java加密库Jasypt 的作者。Thymeleaf旨在替换掉JSP及其他的模板引擎,如Velocity与FreeMarker。它提供了两个版本,分别是Standard方言与SpringStandard(Spring MVC 3)方言,并且可以通过创建自定义方言进行扩展。 Thymeleaf的主要目标在于提供一种可被浏览器正确显示的、格式良好的模板创建方式,因此也可以用作静态建模。你可以使用它创建经过验证的XML与HTML模板。相对于编写逻辑或代码,开发者只需将标签属性添加到模板中即可。接下来,这些标签属性就会在DOM (文档对象模型)上执行预先制定好的逻辑。Thymeleaf的可扩展性也非常棒。你可以使用它定义自己的模板属性集合,这样就可以计算自定义表达式并使用自定义逻辑。这意味着Thymeleaf还可以作为模板引擎框架。 那么Thymeleaf与其他流行的模板引擎如Velocity和FreeMarker相比如何呢?Thymeleaf是与众不同的,因为它使用了自然的模板技术。这意味着Thymeleaf的模板语法并不会破坏文档的结构,模板依旧是有效的XML文档。模板还可以用作工作原型,Thymeleaf会在运行期替换掉静态值。Velocity与FreeMarker则是连续的文本处理器,这样他们就可以处理任何基于文本的模板了。另一方面,Thymeleaf是个XML处理器,它使用了DOM。只能处理基于XML格式的这种限制使得Thymeleaf能够充分利用XML和Web环境所独有的特性。注意,由于Thymeleaf使用了XML DOM解析器,因此它并不适合于处理大规模的XML文件。 下面的代码示例分别使用Velocity、FreeMarker与Thymeleaf打印出一条消息: Velocity: $message FreeMarker: ${message} Thymeleaf:

Hello World! 注意到Thymeleaf去掉了图形化标签,并支持硬编码的文本,在运行期可以将这些文本替换掉。 你可以使用表达式的形式编写Thymeleaf属性,一共有4种类型的属性,分别是变量表达式、选择表达式、文本具化表达式以及URL表达式。变量表达式是Object-Graph Navigation Language(OGNL)表达式,如果使用了SpringStandard,那么还可以使用Spring EL,表达式在上下文图中执行。选择表达式类似于变量表达式,只不过他们是在父对象上执行。你可以通过文本具化表达式从外部资源如.properties文件中检索内容。URL表达式会将上下文与Session信息添加到URL中。感兴趣的读者可以阅读“Getting started with the Standard dialects”这篇文章详细了解Thymeleaf的使用示例。 你可以从SourceForge上下载Thymeleaf并阅读Using Thymeleaf指南来快速上手。如果使用Maven,那么你可以使用org.thymeleaf groupid和thymeleaf artifactId。Thymeleaf最小的依赖是Java SE 5、ognl 3.0、javassist 3.14.0-GA及slf4j 1.6.1。感兴趣的读者可以通过Thymeleaf 官方文档和论坛了解更多信息。

Struts2_Convention_Plugin中文文档

Struts2 Convention Plugin中文文档(一) Introduction 从struts2.1版本开始,Convention Plugin作为替换替换Codebehind Plugin来实现Struts2的零配置。 ?包命名习惯来指定Action位置 ?命名习惯制定结果(支持JSP,FreeMarker等)路径 ?类名到URL的约定转换 ?包名到命名空间(namespace)的约定转换 ?遵循SEO规范的链接地址(即:使用my-action 来替代MyAction) ?基于注解的Action名 ?基于注解的拦截机(Interceptor) ?基于注解的命名空间(Nameespace) ?基于注解的X Work包 ?默认action以及默认的结果(比如:/products 将会尝试寻找com.example.actions.Products 或com.example.actions.products.Index进行处理) 无需配置Convention即可使用Convention,Convention的某些约束习惯可以通过配置属性来控制,您也可以在类中覆写其中的方法来达到扩展目地。 安装 使用Convention插件,你需要将其JAR文件放到你应用的WEB-INF/lib目录中,你也可以在你Maven 项目的POM文件中添加下面包依赖 1. 2. org.apache.struts 3. struts2-convention-plugin 4. 2.1.6 5. 转换基于Codebehind项目到Convention 跳转到此页面,查看需要修改的变化和小提示 如果你想在你系统中结合Convention插件使用REST。需要在你项目的struts.xml中添加如下配置 1. 2. 3. Hello world 到目前为止,你已经在你项目中添加了Convention插件支持,首先我们从一个非常简单的例子开始入手。本例中,我们将演示根据访问URL来访问固定的Action,默认情况下,Convention会默认所

相关文档