velocity 转义 #SJS($js) 和 #SHTML($html) 记录
生活随笔
收集整理的這篇文章主要介紹了
velocity 转义 #SJS($js) 和 #SHTML($html) 记录
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
對于頁面性能優化這塊,尤其是velocity宏的使用,如何使用宏,怎么樣將宏的使用發揮到極致,達到更大的性能的提示,
我的建議如下:
1:一般我們不推薦使用宏,因為宏每次都要要JJT解析,然后才能再執行;
2:使用宏能達到最好的性能情況下,非常安全的,一般在頁面有些信息是用戶輸入的情況
使用會比較好。
下面我針對他的一些意見和我們項目的一些情況,整理了一些關于宏使用的一些技術知識
一:我們如何定義宏和使用宏?
1:定義宏和使用宏
#macro指令用于定義一個VTL模板的重復代碼塊——宏。下面是一個簡單的定義宏的例子:
#macro( d )
<tr><td></td><tr>
#end
這段代碼定義了一個宏,名字為d,沒有參數。下面是使用這個宏的代碼:
#d()
Velocity在遇到#d()的時候,會用"<tr><td></td></tr>"替代上面的#d()這一行。
宏的參數:
宏也可以帶參數,而且是任意多個參數。不過,宏定義時有幾個參數,宏調用時就要提供同樣數目的參數。
#macro( d $name)
??? <tr><td>$name</td></tr>
#end
#d("name1")
宏的參數可以是以下VTL元素中的任意一種:引用、字符串字面值、數值字面值、整數范圍(比如[1 .. 10]、[$start .. $end])、數組、布爾值true或者false。
宏的參數可以是方法,那么下面這個例子,需要特別注意:
#macro(test $a)
??? $a $a $a
#end
#test($foo.bar())
上面這個例子中,$foo.bar()將會被調用3次,而不是一次。
內聯的宏
當宏是在一個Velocity模板中定義時,這個宏(是inline的)只能被該模板使用,同一個網站下的其他模板是不能用的。如果是在一個Velocity宏模板庫中定義的宏,就可以被任何同一網站下的模板使用。
和宏有關的一些Velocity屬性
velocimacro.library——用逗號分隔的一組文件名,是Velocity宏模板庫。默認值是VM_global_library.vm
velocimacro.permissions.allow.inline——宏是否可以在一個普通模板中定義。默認值是false。
velocimacro.permissions.allow.inline.to.replace.global——是否允許模板中的宏覆蓋library中的宏。默認值是false。
velocimacro.permissions.allow.inline.local.scope——一個在普通模板中定義的宏,是否允許其他模板使用。默認是false。
velocimacro.context.localscope——在一個宏里通過#set()修改了context,此修改是否僅僅對這個宏自身,而不是永久性修改了context。默認值是false。
velocimacro.library.autoreload——Velocity宏模板庫修改之后,是否自動重新加載。默認值是false。debug時可以設置為true,發布時設置為false。
其他一些注意點
宏必須在第一次使用它之前定義。當#Parse()一個模板文件時,尤其要注意這一點。
二: 引入指令和#Stop指令
#Include和#Parse都是用于將本地文件引入當前文件的指令,而且被引入的文件必須位于TEMPLATE_ROOT。這兩者之間有一些區別。
#Include
被#Include引入的文件,其內容不會被Velocity引擎解析,所以這些文件應該是靜態模板,即不含有VTL的模板。使用#Include()指令時,參數是被雙引號括起來的文件名或者是表示文件名的變量。如果有多個文件,以逗號隔開即可。比如#Include("a.gif", "b.html", $file)。
#Parse
#Parse用來在當前模板中引入并執行另一個(本地的)模板——可以是靜態的,也可以是動態的——并把結果嵌入到當前位置。#Parse()指令的參數,可以是一個雙引號括起來的文件名,也可以是一個變量,但是它不能接受多個參數。
被#Parse引入的文件仍然可以使用#Parse指令。在velocity.properties文件中有一個屬性directive.parse.max.depth,默認值是10,它指定了#Parse嵌套的最大層次。既然#Parse嵌套是允許的,#Parse遞歸也是允許的。
假如a.vm #Parse b.vm,那么a.vm中定義的變量$v,在b.vm中可以隨便使用。如果b.vm也定義了$v,那么b.vm中用到的將會是自己的$v,而不是a.vm中的$v。
#Stop
#Stop指令會停止模板引擎的執行,并返回。這在debug中比較有用。
三:#include和#parse到底有什么區別?
parse方法是解析文件,宏是全局方法(調用該方法返回數據),調用方法比較快。
#parse是動態加載的,需要***.vm中的宏定義在 velocity啟動的時候就應該得到加載
#include
1.可包含本地文件(不包含VTL)
2.文件內容不經過template engine處理
3.出于安全性的考慮,此文件只能位于TEMPLATE_ROOT目錄下
#parse
1.可以引入包含VTL的模板
2.任何模板文件只能位于TEMPLATE_ROOT目錄下
比如macro.vm里面添加
#macro (static $src)
? $env.getProperties("app.static")/$src
#end
#macro (function_name param_names)
? // code...
#end
這樣使用 #static("...")方法調用
parse與include的區別在于,若包含的文件中有Velocity腳本標簽,將會進一步解析,而include將原樣顯示。
實例1:
#macro(macroName)#end 腳本函數(宏)調用,不推薦在界面模板中大量使用。
如:在使用EasyJWeb Tools快速生成的添刪改查示例中,可以點擊列表的標題欄進行升降排序顯示,這是我們在EasyJWeb應用中經常看到的一個排序狀態顯示的模板內容。
函數(宏)定義,一般放在最前面
#macro(orderPic $type)
#if ($orderField.equals($type))
<img src="/images/ico/${orderType}.gif">
#end
#end
具體的調用如:<font color="#FFFFFF">頭銜#orderPic("title")</font>
實例2:
包含文件#inclue("模板文件名")或#parse("模板文件名")
主要用于處理具有相同內容的頁面,比如每個網站的頂部或尾部內容。
使用方法,可以參考EasyJF開源Blog及EasyJF開源論壇中的應用!
如:#parse("/blog/top.html")或#include("/blog/top.html")
四: Velocity宏使用中需要注意的問題
1、變量輸出要帶上靜止修飾符,避免模板直接空指針報錯
舉例 :$var錯誤,$!var正確
如果變量referce與html代碼連在一起,需要加上{}
舉例 :$! {var}gadsgaggaggas
2、Macro的使用
由于宏存在著安全和性能問題,并且會影響模板的可讀性,在模板中不推薦使用宏。
3、變量引用不要加引號,避免重復轉義舉例:
$stringUtil.equals("$text", "&") 錯誤
$stringUtil.equals($text, "&") 正確
4、關于velocity的版本
目前推薦使用 velocity 1.6.1,因為以往velocity版本往往會出現向下不兼容的情況 版本升級需要經過架構部門(校長)的充分論證和評估才能實施。
5、Velocity的安全性
為避免VELOCITY頁面渲染后產生XSS漏洞,應用應該采用校長的安全方案在應用中引入toolkit-service-velocity.1.5 包。
XSS的過濾,使用velocity提供的xss過濾功能
上述宏,因為非常消耗CPU,因此如果不含特定內容,不到萬不得已,不得使用。
五:總結:
1:模塊化的東西最好不要放入循環當中,parse或者宏都只是加載一段公共的代碼片段而已,循環只是對數據處理來說的;
2:用parse和宏區別不大,parse解析的是一個vm文件,宏返回一段vm代碼,優化的過程不是說使用parse或者宏,而是文件或宏里面的數據處理代碼,這些代碼才有高低效率之分,parse和宏只是在不同場景下不同的使用方法而已。
我的建議如下:
1:一般我們不推薦使用宏,因為宏每次都要要JJT解析,然后才能再執行;
2:使用宏能達到最好的性能情況下,非常安全的,一般在頁面有些信息是用戶輸入的情況
使用會比較好。
下面我針對他的一些意見和我們項目的一些情況,整理了一些關于宏使用的一些技術知識
一:我們如何定義宏和使用宏?
1:定義宏和使用宏
#macro指令用于定義一個VTL模板的重復代碼塊——宏。下面是一個簡單的定義宏的例子:
#macro( d )
<tr><td></td><tr>
#end
這段代碼定義了一個宏,名字為d,沒有參數。下面是使用這個宏的代碼:
#d()
Velocity在遇到#d()的時候,會用"<tr><td></td></tr>"替代上面的#d()這一行。
宏的參數:
宏也可以帶參數,而且是任意多個參數。不過,宏定義時有幾個參數,宏調用時就要提供同樣數目的參數。
#macro( d $name)
??? <tr><td>$name</td></tr>
#end
#d("name1")
宏的參數可以是以下VTL元素中的任意一種:引用、字符串字面值、數值字面值、整數范圍(比如[1 .. 10]、[$start .. $end])、數組、布爾值true或者false。
宏的參數可以是方法,那么下面這個例子,需要特別注意:
#macro(test $a)
??? $a $a $a
#end
#test($foo.bar())
上面這個例子中,$foo.bar()將會被調用3次,而不是一次。
內聯的宏
當宏是在一個Velocity模板中定義時,這個宏(是inline的)只能被該模板使用,同一個網站下的其他模板是不能用的。如果是在一個Velocity宏模板庫中定義的宏,就可以被任何同一網站下的模板使用。
和宏有關的一些Velocity屬性
velocimacro.library——用逗號分隔的一組文件名,是Velocity宏模板庫。默認值是VM_global_library.vm
velocimacro.permissions.allow.inline——宏是否可以在一個普通模板中定義。默認值是false。
velocimacro.permissions.allow.inline.to.replace.global——是否允許模板中的宏覆蓋library中的宏。默認值是false。
velocimacro.permissions.allow.inline.local.scope——一個在普通模板中定義的宏,是否允許其他模板使用。默認是false。
velocimacro.context.localscope——在一個宏里通過#set()修改了context,此修改是否僅僅對這個宏自身,而不是永久性修改了context。默認值是false。
velocimacro.library.autoreload——Velocity宏模板庫修改之后,是否自動重新加載。默認值是false。debug時可以設置為true,發布時設置為false。
其他一些注意點
宏必須在第一次使用它之前定義。當#Parse()一個模板文件時,尤其要注意這一點。
二: 引入指令和#Stop指令
#Include和#Parse都是用于將本地文件引入當前文件的指令,而且被引入的文件必須位于TEMPLATE_ROOT。這兩者之間有一些區別。
#Include
被#Include引入的文件,其內容不會被Velocity引擎解析,所以這些文件應該是靜態模板,即不含有VTL的模板。使用#Include()指令時,參數是被雙引號括起來的文件名或者是表示文件名的變量。如果有多個文件,以逗號隔開即可。比如#Include("a.gif", "b.html", $file)。
#Parse
#Parse用來在當前模板中引入并執行另一個(本地的)模板——可以是靜態的,也可以是動態的——并把結果嵌入到當前位置。#Parse()指令的參數,可以是一個雙引號括起來的文件名,也可以是一個變量,但是它不能接受多個參數。
被#Parse引入的文件仍然可以使用#Parse指令。在velocity.properties文件中有一個屬性directive.parse.max.depth,默認值是10,它指定了#Parse嵌套的最大層次。既然#Parse嵌套是允許的,#Parse遞歸也是允許的。
假如a.vm #Parse b.vm,那么a.vm中定義的變量$v,在b.vm中可以隨便使用。如果b.vm也定義了$v,那么b.vm中用到的將會是自己的$v,而不是a.vm中的$v。
#Stop
#Stop指令會停止模板引擎的執行,并返回。這在debug中比較有用。
三:#include和#parse到底有什么區別?
parse方法是解析文件,宏是全局方法(調用該方法返回數據),調用方法比較快。
#parse是動態加載的,需要***.vm中的宏定義在 velocity啟動的時候就應該得到加載
#include
1.可包含本地文件(不包含VTL)
2.文件內容不經過template engine處理
3.出于安全性的考慮,此文件只能位于TEMPLATE_ROOT目錄下
#parse
1.可以引入包含VTL的模板
2.任何模板文件只能位于TEMPLATE_ROOT目錄下
比如macro.vm里面添加
#macro (static $src)
? $env.getProperties("app.static")/$src
#end
#macro (function_name param_names)
? // code...
#end
這樣使用 #static("...")方法調用
parse與include的區別在于,若包含的文件中有Velocity腳本標簽,將會進一步解析,而include將原樣顯示。
實例1:
#macro(macroName)#end 腳本函數(宏)調用,不推薦在界面模板中大量使用。
如:在使用EasyJWeb Tools快速生成的添刪改查示例中,可以點擊列表的標題欄進行升降排序顯示,這是我們在EasyJWeb應用中經常看到的一個排序狀態顯示的模板內容。
函數(宏)定義,一般放在最前面
#macro(orderPic $type)
#if ($orderField.equals($type))
<img src="/images/ico/${orderType}.gif">
#end
#end
具體的調用如:<font color="#FFFFFF">頭銜#orderPic("title")</font>
實例2:
包含文件#inclue("模板文件名")或#parse("模板文件名")
主要用于處理具有相同內容的頁面,比如每個網站的頂部或尾部內容。
使用方法,可以參考EasyJF開源Blog及EasyJF開源論壇中的應用!
如:#parse("/blog/top.html")或#include("/blog/top.html")
四: Velocity宏使用中需要注意的問題
1、變量輸出要帶上靜止修飾符,避免模板直接空指針報錯
舉例 :$var錯誤,$!var正確
如果變量referce與html代碼連在一起,需要加上{}
舉例 :$! {var}gadsgaggaggas
2、Macro的使用
由于宏存在著安全和性能問題,并且會影響模板的可讀性,在模板中不推薦使用宏。
3、變量引用不要加引號,避免重復轉義舉例:
$stringUtil.equals("$text", "&") 錯誤
$stringUtil.equals($text, "&") 正確
4、關于velocity的版本
目前推薦使用 velocity 1.6.1,因為以往velocity版本往往會出現向下不兼容的情況 版本升級需要經過架構部門(校長)的充分論證和評估才能實施。
5、Velocity的安全性
為避免VELOCITY頁面渲染后產生XSS漏洞,應用應該采用校長的安全方案在應用中引入toolkit-service-velocity.1.5 包。
XSS的過濾,使用velocity提供的xss過濾功能
1)對于html,可以使用? #SHTML($html)
2)對于JS,可以用 #SJS($js)
3)對于xml,可以使用#SXML($xml)
4)屏蔽轉義,可以使用#SLITERAL()上述宏,因為非常消耗CPU,因此如果不含特定內容,不到萬不得已,不得使用。
五:總結:
1:模塊化的東西最好不要放入循環當中,parse或者宏都只是加載一段公共的代碼片段而已,循環只是對數據處理來說的;
2:用parse和宏區別不大,parse解析的是一個vm文件,宏返回一段vm代碼,優化的過程不是說使用parse或者宏,而是文件或宏里面的數據處理代碼,這些代碼才有高低效率之分,parse和宏只是在不同場景下不同的使用方法而已。
總結
以上是生活随笔為你收集整理的velocity 转义 #SJS($js) 和 #SHTML($html) 记录的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PTA 7-4 十进制转二进制 (10
- 下一篇: Unity开发VR——Oculus Ri