httl页面静态化模板帮助文档.docx_第1页
httl页面静态化模板帮助文档.docx_第2页
httl页面静态化模板帮助文档.docx_第3页
httl页面静态化模板帮助文档.docx_第4页
httl页面静态化模板帮助文档.docx_第5页
已阅读5页,还剩36页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1.概述HTTL(Hyper-Text Template Language)是一个高性能的JAVA开源模板引擎,适用于动态HTML页面输出,可替代JSP页面,它的指令和Velocity相似。 快速将模板编译成JAVA字节码运行,并使用强类型推导,减少运行期反射和转型,渲染速度是Velocity,Freemarker等其它模板引擎的10倍,请参见第3章的性能对比。注:JSP只有Scriptlet是编译的,Tag和EL是解释执行的,而HTTL是全编译的。简洁保持最简洁指令集,只保留基本的占位/注释/转义,和八个必需的控制指令,其它都降级为表达式方法实现,比如:$!include(a.httl)。直觉语法尽可能符合HTML和JAVA开发者的直觉,指令类似于常用Velocity指令,但改进了Velocity中不符合直觉的地方,请参见第5章与Velocity的对比。友好模板自描述,在模板内声明入参变量类型,并基于入参类型推导模板内所有变量类型,使IDE能方便的实现变量方法补全提示,对开发过程友好。2.示例2.1 调用示例BooksServlet.java:import httl.*;import java.util.*;Map parameters = new HashMap();parameters.put(user, user);parameters.put(books, books);Engine engine = Engine.getEngine();Template template = engine.getTemplate(books.httl);template.render(parameters, response.getWriter();注:缺省配置下,HTTL不依赖任何三方库,只需JDK1.5+即可。2.2 模板示例books.httl:!-#var(User user, List books)- $book.title 2.3 配置示例perties:import.packages+=com.xxxtemplate.directory=META-INF/templatesinput.encoding=UTF-8output.encoding=UTF-8其中,+=表示追加配置,而不覆盖缺省配置。注意,所有配置项都有缺省值,如果使用缺省值,可以不配,更多配置参见文档第7章。3.性能3.1 性能对比性能测试类:PerformanceTest.java引擎模板初始化编译首渲染输出大小十万渲染每秒次数javabooks.java0ms1ms0ms28,778byte8,739ms11,442/shttlbooks.httl88ms621ms3ms28,778byte9,608ms10,407/svelocitybooks.vm21ms96ms23ms28,172byte41,969ms2,382/sfreemarkerbooks.ftl103ms121ms141ms27,571byte56,192ms1,779/ssmarty4jbooks.st2ms75ms18ms29,044byte65,855ms1,518/sbeetlbooks.btl24ms11ms159ms26,820byte81,428ms1,228/s环境:os: Mac OS X 10.8.2, cpu: 2 x 1.70GHz, mem: 4G, jvm: 1.7.0_09 - mem: 80MHTTL的渲染速度接近于直接用Java硬编码输出,比其它模板引擎高出10倍。HTTL用到的JDK的Compiler,编译一个类通常需要几百毫秒,比其它模板的编译要慢,但每个模板只在加载时编译一次。注:不同环境的运行结果可能存在差异,以上测试数据仅供参考,你可以在自己的机器上执行测试:git clone /httl/httl.gitcd httlmvn test -Dtest=httl.test.PerformanceTest -Dstream=false -Dsize=200 -Dcount=10000另外,HTTL缺省开启了EscapeXmlFilter,而其它模板引擎没有,为了公平,性能测试时配置关闭了Filter:value.filters=null3.2 优化策略3.2.1 强类型编译,并推导关联类型对于表达式$的编译:弱类型字节码生成:Object user = context.get(user); / 无法确定user是Map还是POJO/ 反射获取属性的值,而且要运行期判断是user.getName(),还是字段Object name = ReflectUtil.get(user, name); / 接下来name也要反射HTTL强类型字节码生成:User user = (User)context.get(user); / 通过in=User user声明类型/ 编译期通过User的字段类型推演name的类型,并在编译期决定使用getName()String name = user.getName();3.2.2 编译时就将文本编译成字节,加快输出文本编译:writer.write();writer.write(user.getName();二进制编译:output.write(new byte 60, 116, 97, 98, 108, 101, 62, 60, 116, 114, 62, 60, 116, 100, 62);output.write(user.getName().getBytes();这样可以大幅度降低IO输出时将文本通过字符集编码成二进制流的速度。HTTL缺省每模板同时生成两份class,在用户传入OutputStream和Writer时,执行不同的class:template.render(paramaters, outputStream); / 内部将执行二进制输出版本的Template类template.render(paramaters, writer); / 内部将执行文本输出版本的Template类3.2.3 对于赋值生成局部变量,不put回参数map比如将:$price编译成:int price = price * discount / 100;write(price);而不是:context.put(price, price * discount / 100);write(context.get(price);这样可以大量减少参数map的put和get的调用。3.2.4 将文本不编译到字节码中,减少内存perm区占用,以及防止JIT失效:当模板的内容较大时,会导致生成的字节码也比较大,字节码运行时会放在内存perm区,导致perm区过大。模板多时,用户可能需要不断调大perm区:java -XX:PermSize=256MB -XX:MaxPermSize=256MB另外,SunJDK缺省对大于8K字节码的方法不进行JIT优化,我们常规开启的JVM是mixed模式的,即调用量大的,将由JIT编译成本地码运行,其它在JVM内解释执行,解释执行和编译执行的速度相差10倍以上。参见JVM的:globals.hppproduct(bool, DontCompileHugeMethods, true, dont compile methods HugeMethodLimit)develop(intx, HugeMethodLimit, 8000, dont compile methods larger than this if +DontCompileHugeMethods)通过将文本不编译到字节码中,减少内存perm区占用,也能防止JIT失效。3.2.5 减少反射调用,以及基本类型装箱。因为模板输出的大量是基本类型和字符串,Httl遇到任何类似需要boxed和unboxed的地方,都会重载所有基本类型方法,以减少boxed和unboxed的处理。比如:当输出基本类型时,需要转成String,如果使用format(Object)接口,就会将基本类型装箱。反射也经常是性能瓶颈所在,比如:因为int不继承于Object,为了通用处理,改为Array.get(array, index)来获取数组的项,导致在Profiler分析时,发现80%的CPU时间都耗在Array.get()上。等等。4.设计4.1 类关系查看大图4.1.1 核心领域模型划分原则:按实体域,服务域,会话域划分。不管你做一个什么产品,都一定有一个被操作的主体,比如:服务框架管理的Service,任务框架管理的Task,Spring管理的Bean等,这就是实体域。即然有被操作者,就一定有操作者,它管理被操作者的生命周期,发起动作,比如:服务框架的ServiceInvoker,,任务框架的TaskScheduler,Spring的BeanFactory等,这就是服务域。服务域发起动作,在执行过程中,会有一些临时状态需要存储交换,比如:Invacation,Execution,Request等,这就是会话域。相应的,在HTTL中: Engine 为服务域,它是API的入口,并负责实体域Template的生命周期管理,它是Singleton实例的,加载后不可变,所以是线程安全的,它的初始化过程较重,请复用单例。 Template 为实体域,代表着被操作者,它是Prototype实例的,即每个模板产生一个实例,加载后不可变,同样也是线程安全的,模板变化后,将产生不同的实例,而不改变原实例。 Context 为会话域,执有操作过程的可变状态,它是ThreadLocal实例的,即不和其它线程竞争使用,所以也是线程安全的,请不要跨线程传递,它的初始化轻量,每次执行新建实例,执行完即销毁。这样划分的好处是,职责清晰,可变状态集中,每个域都是无锁线程安全的,保证在大并发下,不会降低系统的活性。4.1.2 分包原则:按复用度,抽象度,稳定度分包。 复用度:每种用户所需用到的类,就是同一复用粒度的,比如:使用者和扩展者,这样可以减少代码干扰,以及最大化复用。 抽象度:包中抽象类个数占比,比如包中有10个类,其中3个为抽象类(包括接口),则抽象度为3/10,保持被依赖者总是比依赖者的抽象度高,形成金子塔关系,这样可以保持每层都有足够的扩展性。 稳定度:被依赖包和依赖包的占比,如果一个包依赖很多包,那别的包变化都会引起它跟随变化,所以它就不稳定,反之即稳定,保持包的稳定度和抽象度成正比,即把抽象类(包括接口)放到稳定的包中,这样可以防止不稳定性传染。稳定度与抽象度关系如下图:也就是分包应该如下:其中上面那个包不依赖其它包。所以它很稳定,应尽量把抽象类或接口放在这一层,而下面那个包依赖了三个包,三个包变化会引起它跟随变化,所以它是不稳定,应尽量把具体实现类放在这一层。因稳定度与抽象度成正比,所以不稳定度与抽象度成反比,计算方式如下:(1) I = Ce / (Ca + Ce) I: Instability (不稳定度) Ca: Afferent Coupling (传入依赖,也就是被其它包依赖的个数) Ce: Efferent Coupling (输出依赖,也就是依赖其它包的个数)(2) A = Na / Nc A: Abstractness (抽象度) Na: Number of abstract classes (抽象类的个数) Nc: Number of classes (类的个数,包括抽象类)(3) D = abs(1 - I - A) * sin(45) D: Distance (偏差) I: Instability (不稳定度) A: Abstractness (抽象度)应该保持偏差越小越好,即下图所示交点都落在绿色反比线左右:基于上面的原则,HTTL的包结构整体上划分为三层: API (Application Programming Interface) 模板引擎的使用者依赖的接口类,也是核心领域模型,其中Engine类相当于微内核,只管理非功能性的扩展点的加载,不硬编码模板加载解析渲染的任何部分。 SPI (Service Provider Interface) 模板引擎的扩展者依赖的接口类,它依赖于API的领域模型,它是模板引擎功能正交分解的抽象层,以保证用户可以最小粒度替换需要改写的地方,方便二次开发。 BUILT-IN (Built-in Implementation) 内置扩展实现,它是SPI标准实现,也是可被用户替换的类,它包含引擎所有做的事,包括扩展点之间的组装过程(可替换DefaultEngine),以确保没有功能换不掉,即平等对待扩展者。 采用子包依赖父包风格,所以将API放在根目录,SPI接口独立子包,各种实现放在SPI的下一级子包中。 使用者API导入: import httl.*; 扩展者SPI导入:import httl.spi.*;下图是HTTL所有包的不稳定度与抽象度的比值距阵:HTTL所有核心包都是靠近反比线的,即上图用绿色标识的,表示分包是合理的。4.2 调用过程查看大图执行过程说明:(与上图中的序号对应) 1 当从引擎中获取模板时, 1.1 首先会在缓存查找是否已缓存,如果有缓存就直接返回, 1.2 如果没有,则加载模板, 1.3 接着进行模板语法解析, 1.3.1 在解析到表达式时,将其转译为Java表达式, 1.3.2 并对静态文本进行编译前过滤,比如删除空白等, 1.3.3 对解析后的Java代码进行编译,得到Template的具体模板实现类, 1.3.4 实例化模板实现类, 1.4 将模板实例写入缓存,并返回给用户, 2 当用户调用模板的渲染方法时, 2.1 将动态占位符内容,先格式化成字符串, 2.2 再进行过滤,比如转义动态内容的HTML特殊符,2.3 然后输出过滤后的内容,如果是静态文本直接输出。5.指令基于Velocity指令和Html注释:5.0 与Velocity对比如果你用过Velocity模板,可以查看以下对比,加深了解:5.0.1 语法对比1. HTTL指令必需加注释外壳,只支持,不支持#if(x),确保不干扰HTML本身的有效源码。 2. HTTL指令中的变量不加$符,只支持,不支持,因为指令中没有加引号的字符串就是变量,和常规语言的语法一样,加$有点废话,而且容易忘写。3. HTTL占位符必需加大括号,只支持$aaa,不支持$aaa,因为$在JavaScript中也是合法变量名符号,而$不是,减少混淆,也防止多人开发时,有人加大括号,有人不加,干脆没得选,都加,保持一致。 4. HTTL占位符当变量为null时输出空白串,而不像Velocity那样原样输出指令原文,即$aaa,等价于Velocity的$!aaa,以免开发人员忘写感叹号,泄漏表达式源码,如需原样输出,可使用转义$aaa,在HTTL中,$!aaa表示不对内容进行过滤,用于原样输出HTML片段。5. HTTL支持在所有使用变量的地方,进行表达式计算,也就是你不需要像Velocity那样,先#set($j = $i + 1),再#if($j = $m),可以直接,其它指令也一样。6. HTTL采用扩展Class原生方法的方式,如:$a.toChar,而不像Velocity的Tool工具方法那样:$(StringTool.toChar(a),这样的调用方式更直观,更符合代码书写习惯。5.0.2 指令对比HTTLVelocity异同功能$xxx.yyy$xxx.yyy$xxx.yyy相同输出占位符$!xxx.yyy$!xxx.yyy$!xxx.yyy不同一个是不过滤,一个是不原样输出# .#* . *#相似不显示注释块# . #相似不解析文本块# $ # $ 相同特殊符转义不支持不同定义输入参数类型#set($xxx = $yyy)相同给变量赋值#if($xxx = $yyy)相同条件判断#elseif($xxx = $yyy)相同否则条件判断#else相同否则判断#end相同结束指令#foreach($item in $list)相同列表循环#if($xxx = $yyy) #break #end相似中断循环#macro($xxx)相似宏替换,模板片断#define($xxx)相似捕获块输出到变量中$!read(xxx.txt)#include(xxx.txt)相似读取文本文件内容$!include(xxx.httl)#parse(xxx.vm)相似包含另一模板输出$!evaluate(1 + 2)#evaluate(1 + 2)相似表达式求值不支持#stop不同停止模板解析5.1 输出指令5.1.1 过滤输出输出表达式的计算结果,并进行过滤,比如:过滤变量中的HTML标签,防止HTML注入攻击。格式:$expression示例:$5.1.2 不过滤输出原样输出表达式的计算结果,不进行任何过滤,通常用于输出HTML片段。格式:$!expression示例:$!body5.2 变量定义指令5.2.1 类型声明声明输入变量的类型,模板内部其它变量类型基于此类型推导。格式:示例:5.2.2 变量赋值将表达式的计算结果存入变量中。格式:示例:缺省模板中set的变量,是不会回写到Context的参数Map中的。你需要用“:=”进行赋值,才会回写到Context的参数Map中:格式:示例:你可以通过ThreadLocal的Context.getContext().getParameters()拿到回写的变量:/ 你可以把入参设成不可修写的Map,不会影响运行。Map parameters = Collections.unmodifiableMap(parameters);/ 传入的parameters在渲染过程中总是不会被修复,确保渲染过程无副作用,以及多次渲染的幂等性。template.render(parameters, writer);/ 注意:这里获取到的并不是上面render参入的parameters,而是parameters的包装类。/ 此parameters是可写的,当模板中set回写变量时,写入该Map中。/ 在查询变量时,先在包装类中查找,找不到,再到原生传入的parameters中查找。Context.getContext().getParameters().get(price);5.3 条件指令5.3.1 IF条件如果条件表达式计算结果为真或非空,则输出指令所包含的块。格式:示例: .5.3.2 ELSEIF条件如果前面的IF条件不为真,并且当前条件表达式计算结果为真或非空,则输出指令所包含的块。格式:示例: . .5.3.3 ELSE条件如果前面的IF条件不为真,则输出指令所包含的块。格式:示例: . .5.4 迭代指令5.4.1 集合迭代迭代表达式产生的集合,以集合中的每项值,重复输出指令所包含的块。格式:示例: . $foreach.index $foreach.size $foreach.first $foreach.last5.4.3 中断迭代当条件表达式为真或非空时,中断当前迭代过程。格式:示例: . .5.5 宏指令将指令块封装成可复用的模板片断,在声明处不执行,在调用时再执行。格式:示例: .$!xxx(books)5.6 字面指令5.6.1 注释块隐藏注释的内容,用于注解过程,或屏蔽指令内容。格式:示例:5.6.2 不解析块原样输出模板内容,用于输出纯文本内容。格式:示例:5.6.3 特殊符转义原样输出指令特殊符,用于输出纯文本内容。格式:#, $, 示例:$xxx6.表达式基于Java表达式和扩展方法。支持Java所有表达式,以下只列出与Java不同的点: 所有null值的操作均返回null。 所有实现Comparable的对象都支持比较运算符。 所有对象都支持逻辑与或,分别返回空值或非空值。6.1 操作符表达式6.1.1 集合操作符Sequence: 1.3List: 123, abcMap: xxx: 123, yyy: abc6.1.2 日期操作符date1 date2date1 = date2date1 date2date1 = date26.1.3 逻辑操作符等价于:等价于: 0)-等价于: 0)-等价于: 0 ? list1 : list2)-6.2 函数表达式6.2.1 转型函数obj.to(com.foo.Bar)num.toDatestr.toDatestr.toDate(yyyy-MM-dd HH:mm:ss)str.toCharstr.toBooleanstr.toBytestr.toIntstr.toLongstr.toFloatstr.toDoublestr.toClass6.2.2 转义函数str.escapeXmlstr.escapeUrlstr.escapeString6.2.3 格式化函数num.format(#,#0)num.format(#,#0.#)date.format(yyyy-MM-dd)date.format(yyyy-MM-dd HH:mm:ss)6.2.4 集合函数arrayindexlistindexmap.keymapkey$item.xxx$item.xxx$entry.key$entry.valuesort(list)cycle(item, item)$colors.next6.2.5 文件函数include(template.httl)include(template.httl, UTF-8)include(locale(i18n-template.httl)read(text.txt)read(text.txt, UTF-8)read(locale(i18n-text.txt)6.2.6 系统函数now()random()uuid()7.配置配置中,+=表示在缺省配置上追加配置,=表示覆盖缺省配置。7.1 模板引擎配置engine=httl.spi.engines.DefaultEngineparser=httl.spi.parsers.CommentParsertranslator=httl.spi.translators.DfaTranslator其中,engine负责组装,parser负责解析语法,translator负责将模板表达式翻译成java表达式。除非你想改变语法,或优化解析性能,否则此三项不需要配置。如果你喜欢HTML标签属性语法,可以配置:parser=httl.spi.parsers.AttributeParser语法如: $book.title 如果属性和其它框架冲突,可以添加名字空间:space=httl属性语法需要用到jericho包解析HTML标签:jericho-html-3.1.jar net.htmlparser.jericho jericho-html 3.1名称空间写法如:你可以设置foreach状态的变量名,缺省为foreach:(缺省值不用配)foreach.status=foreach7.2 模板缓存配置缺省为强缓存,即所有模板和表达式加载后全部缓存:(缺省值不用配)template.cache=java.util.concurrent.ConcurrentHashMapexpression.cache=java.util.concurrent.ConcurrentHashMap如果你的模板非常之多,内存不足以缓存所有模板,可以配置为LRU缓存:template.cache=httl.spi.caches.LruCachecache.capacity=10000你可以用cache同时设置模板和表达式两者的缓存:cache=httl.spi.caches.LruCache等价于:template.cache=httl.spi.caches.LruCacheexpression.cache=httl.spi.caches.LruCache如果不需要缓存,请设为:cache=null7.4 模板加载配置(1) 可以配置启动时预编译所有模板,会调用loader.list()扫描模板文件。template.suffix用于loader.list()过滤模板文件。预编译缺省关闭:(缺省值不用配)precompiled=falsetemplate.suffix=.httl(2) 可以配置是否允许热加载,缺省为false:(缺省值不用配)reloadable=false开启热加载后,模板引擎在getTemplate()时会检查文件的lastModified时间,如果比上次加载的时间新,就重新加载。请注意:旧的模板不会被卸载,经常改文件会导致内存perm区越来越大,只能在开发阶段使用。(3) 可以配置模板加载缺省编码,缺省为UTF-8:(缺省值不用配)input.encoding=UTF-87.4.1 从Classpath下加载缺省从Classpath下加载,即模板放在任意jar包中:(缺省值不用配)loaders=httl.spi.loaders.ClasspathLoadertemplate.directory=7.4.2 从文件加载:loaders=httl.spi.loaders.FileLoadertemplate.directory=/home/admin/templates7.4.3 从jar包中加载:loaders=httl.spi.loaders.JarLoadertemplate.directory=/home/admin/tempaltes.jar7.4.4 从zip包中加载:loaders=httl.spi.loaders.ZipLoadertemplate.directory=/home/admin/tempaltes.zip7.4.5 从指定url加载:loaders=httl.spi.loaders.UrlLoadertemplate.directory=http:/myhost/tempaltes7.4.6 从war包加载:loaders=httl.spi.loaders.ServletLoadertemplate.directory=/WEB-INF/templates需在web.xml中配置ServletLoader的listener: httl.spi.loaders.ServletLoader7.4.7 从内存字符串加载:loaders=httl.spi.loaders.StringLoader然后编码加入模板内容:StringLoader.addResource(foo.httl, $);7.4.8 从多个源加载:loaders=httl.spi.loaders.ClasspathLoader,httl.spi.loaders.FileLoader或者使用+=保留缺省的classpath加载的同时,增加新的加载器:loaders+=httl.spi.loaders.FileLoader7.5 模板编译器用于将模板类编译成字节码,缺省使用jdk自带的编译器:(缺省值不用配)compiler=pilers.JdkCompiler你也可以换成javassist编译:compiler=pilers.JavassistCompiler当然,也就需要增加javassist的jar包依赖:javassist-3.15.0-GA.jar org.javassist javassist 3.15.0-GA(1) 输出选项:如果设置output.stream=true,在编译期就会将模板文件转换成byte数据,在输出时,直接向OutputStream中输出byte流,以免运行期每次输出都要转一次。缺省全部开启:(缺省值不用配)output.stream=trueoutput.writer=true如果output.stream和output.writer同时开启,每份模板将编译成两份class,并返回自适应Template代理类。当用户调用template.render(Map,OutputStream)时,实际执行输出byte的Template类,当用户调用template.render(Map,Writer)时,实际执行输出String的Template类。如果output.stream和output.writer同时关闭,只生成writer模板,相当于只开启output.writer。注意:如果只开启output.stream=true,必须用template.render(Map,OutputStream),否则数据转换会导致性能更低。如果只开启output.writer=true,必须用template.render(Map,Writer),否则数据转换会导致性能更低。如果你从来不传入OutputStream或Writer,请关闭相应配置开关,减少编译开销。(2) 内存选项:缺省将模板源码和模板文本都不编译到字节码中:(缺省值不用配)source.in.class=falsetext.in.class=false它通过一个Map缓存做中介,把模板源码和模板文本都放到了runtime属性中,以节省内存perm区大小。编译到字节码中,在小模板时,可能会稍快,但不会有质的飞跃,在模板大于8K时,会导致JVM的JIT优化失效,会更慢,不建议改变此选项。(3) 版本选项:java版本的配置会影响字节码生成的版本。java.version=1.6(4) 调试选项:如果你想知道编译后的字节码是什么样的,可以开启debug模式,并设置编译目录,编译器会向指定目录输出.class文件。调试缺省关闭:(缺省值不用配)debug=falsecompile.directory=7.6 输出格式化器缺省加载了日期格式化器:(缺省值不用配)formatters=httl.spi.formatters.DateFormatterdate.format=yyyy-MM-dd HH:mm:sstime.zone=你也可以设置时区,设置后,格式化的结果会带上时区的值:(缺省为当前系统时区)time.zone=+8你可以使用+=保留缺省的日期格式化器的同时,增加新的格式化器:formatters+=httl.spi.formatters.NumberFormatternumber.format=#,#0.#你还可以设置null,true,false值的输出,null值缺省会输出空白,true,false原样输出:(缺省值不用配)null.value=true.value=truefalse.value=false比如可以配为:null.value=N/Atrue.value=yesfalse.value=no7.7 输出过滤器过滤器分为两类,一类是针对模板文本的,一类是针对动态插值的。模板文本过滤会在编译的时候执行,编译时即把模板文本替换掉,不影响输出时的性能。动态插值的过滤会在输出的时候执行,需小心过滤引起性能问题。缺省加载了动态插值HTML过滤,防止HTML注入XSS攻击:(缺省值不用配)value.filters=httl.spi.filters.EscapeXmlFiltertext.filters=你可以配置在编译时将静态文本中的空白行删除:(编译时执行,不影响渲染速度)text.filters=httl.spi.filters.ClearBlankLineFilter你也可以配置在编译时将静态文本中的连续空白符压缩成单个空格:(编译时执行,不影响渲染速度)text.filters=httl.spi.filters.CompressBlankFilter你也可以用filters同时设置value.filters和text.filters:filters=httl.spi.filters.CompressBlankFilter等价于:value.filters+=httl.spi.filters.CompressBlankFiltertext.filters+=httl.spi.filters.CompressBlankFilter7.8 类型导入7.8.1 导入包名import.packages=java.util这样你就可以在模板内用短类名,而不用带上全包名。7.8.2 导入方法缺省导入DefaultMethod类中的方法:(缺省值不用配)import.methods=httl.spi.methods.DefaultMethod你可以使用+=保留缺省方法的同时,导入新的方法:import.methods+=com.foo.MyMethod比如DefaultMethod有静态方法:(也可以是非静态方法)public static String format(Date self,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论