以下内容全部是网上收集:
FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主要由如下4个部分组成: 1,文本:直接输出的部分 2,注释:<#-- ... -->格式部分,不会输出 3,插值:即${...}或#{...}格式的部分,将使用数据模型中的部分替代输出 4,FTL指令:FreeMarker指定,和HTML标记类似,名字前加#予以区分,不会输出
下面是一个FreeMarker模板的例子,包含了以上所说的4个部分
Welcome! <#-- 注释部分 -->
<#-- 下面使用插值 -->
Welcome ${user} ! We have these animals: <#-- 使用FTL指令 --> <#list animals as being> ${being.name} for ${being.price} Euros <#list>
1, FTL指令规则
在FreeMarker中,使用FTL标签来使用指令,FreeMarker有3种FTL标签,这和HTML标签是完全类似的. 1,开始标签:<#directivename parameter> 2,结束标签:#directivename> 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} ${answer} 输出结果是: $42.00 $42.00 42 $42.00 4,200% 3,插值结果为日期值:根据默认格式(由#setting指令设置)将表达式结果转换成文本输出.可以使用内建的字符串函数格式化单个插值,如下面的例子: ${lastUpdated?string("yyyy-MM-dd HH:mm:ss zzzz")} ${lastUpdated?string("EEE, MMM d, ''yy")} ${lastUpdated?string("EEEE, MMMM dd, yyyy, hh:mm:ss a '('zzz')'")} 输出结果是: 2008-04-08 08:08:08 Pacific Daylight Time Tue, Apr 8, '03 Tuesday, April 08, 2003, 08:08:08 PM (PDT) 4,插值结果为布尔值:根据默认格式(由#setting指令设置)将表达式结果转换成文本输出.可以使用内建的字符串函数格式化单个插值,如下面的例子: <#assign foo=true/> ${foo?string("yes", "no")} 输出结果是: yes
2.2 数字格式化插值
数字格式化插值可采用#{expr;format}形式来格式化数字,其中format可以是: mX:小数部分最小X位 MX:小数部分最大X位 如下面的例子: <#assign x=2.582/> <#assign y=4/> #{x; M2} <#-- 输出2.58 --> #{y; M2} <#-- 输出4 --> #{x; m2} <#-- 输出2.6 --> #{y; m2} <#-- 输出4.0 --> #{x; m1M2} <#-- 输出2.58 --> #{x; m1M2} <#-- 输出4.0 -->
3, 表达式
表达式是FreeMarker模板的核心功能,表达式放置在插值语法${}之中时,表明需要输出表达式的值;表达式语法也可与FreeMarker标签结合,用于控制输出.实际上FreeMarker的表达式功能非常强大,它不仅支持直接指定值,输出变量值,也支持字符串格式化输出和集合访问等功能.
3.1 直接指定值
使用直接指定值语法让FreeMarker直接输出插值中的值,而不是输出变量值.直接指定值可以是字符串,数值,布尔值,集合和MAP对象.
1,字符串 直接指定字符串值使用单引号或双引号限定,如果字符串值中包含特殊字符需要转义,看下面的例子: ${"我的文件保存在C:\\盘"} ${'我名字是\"annlee\"'} 输出结果是: 我的文件保存在C:\盘 我名字是"annlee"
FreeMarker支持如下转义字符: \";双引号(u0022) \';单引号(u0027) \\;反斜杠(u005C) \n;换行(u000A) \r;回车(u000D) \t;Tab(u0009) \b;退格键(u0008) \f;Form feed(u000C) \l;< \g;> \a;& \{;{ \xCode;直接通过4位的16进制数来指定Unicode码,输出该unicode码对应的字符.
如果某段文本中包含大量的特殊符号,FreeMarker提供了另一种特殊格式:可以在指定字符串内容的引号前增加r标记,在r标记后的文件将会直接输出.看如下代码: ${r"${foo}"} ${r"C:\foo\bar"} 输出结果是: ${foo} C:\foo\bar
2,数值 表达式中的数值直接输出,不需要引号.小数点使用"."分隔,不能使用分组","符号.FreeMarker目前还不支持科学计数法,所以"1E3"是错误的.在FreeMarker表达式中使用数值需要注意以下几点: 1,数值不能省略小数点前面的0,所以".5"是错误的写法 2,数值8 , +8 , 8.00都是相同的
3,布尔值 直接使用true和false,不使用引号.
4,集合 集合以方括号包括,各集合元素之间以英文逗号","分隔,看如下的例子: <#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as x> ${x} #list> 输出结果是: 星期一 星期二 星期三 星期四 星期五 星期六 星期天
除此之外,集合元素也可以是表达式,例子如下: [2 + 2, [1, 2, 3, 4], "whatnot"]
还可以使用数字范围定义数字集合,如2..5等同于[2, 3, 4, 5],但是更有效率.注意,使用数字范围来定义集合时无需使用方括号,数字范围也支持反递增的数字范围,如5..2
5,Map对象 Map对象使用花括号包括,Map中的key-value对之间以英文冒号":"分隔,多组key-value对之间以英文逗号","分隔.下面是一个例子: {"语文":78, "数学":80} Map对象的key和value都是表达式,但是key必须是字符串
3.2 输出变量值
FreeMarker的表达式输出变量时,这些变量可以是顶层变量,也可以是Map对象中的变量,还可以是集合中的变量,并可以使用点(.)语法来访问Java对象的属性.下面分别讨论这些情况
1,顶层变量 所谓顶层变量就是直接放在数据模型中的值,例如有如下数据模型: Map root = new HashMap(); //创建数据模型 root.put("name","annlee"); //name是一个顶层变量
对于顶层变量,直接使用${variableName}来输出变量值,变量名只能是字母,数字,下划线,$,@和#的组合,且不能以数字开头号.为了输出上面的name的值,可以使用如下语法: ${name}
2,输出集合元素 如果需要输出集合元素,则可以根据集合元素的索引来输出集合元素,集合元素的索引以方括号指定.假设有索引: ["星期一","星期二","星期三","星期四","星期五","星期六","星期天"].该索引名为week,如果需要输出星期三,则可以使用如下语法: ${week[2]} //输出第三个集合元素
此外,FreeMarker还支持返回集合的子集合,如果需要返回集合的子集合,则可以使用如下语法: week[3..5] //返回week集合的子集合,子集合中的元素是week集合中的第4-6个元素
3,输出Map元素 这里的Map对象可以是直接HashMap的实例,甚至包括JavaBean实例,对于JavaBean实例而言,我们一样可以把其当成属性为key,属性值为value的Map实例.为了输出Map元素的值,可以使用点语法或方括号语法.假如有下面的数据模型: Map root = new HashMap(); Book book = new Book(); Author author = new Author(); author.setName("annlee"); author.setAddress("gz"); book.setName("struts2"); book.setAuthor(author); root.put("info","struts"); root.put("book", book);
为了访问数据模型中名为struts2的书的作者的名字,可以使用如下语法: book.author.name //全部使用点语法 book["author"].name book.author["name"] //混合使用点语法和方括号语法 book["author"]["name"] //全部使用方括号语法
使用点语法时,变量名字有顶层变量一样的限制,但方括号语法没有该限制,因为名字可以是任意表达式的结果.
3.3, 字符串操作
FreeMarker的表达式对字符串操作非常灵活,可以将字符串常量和变量连接起来,也可以返回字符串的子串等.
字符串连接有两种语法: 1,使用${..}或#{..}在字符串常量部分插入表达式的值,从而完成字符串连接. 2,直接使用连接运算符+来连接字符串
例如有如下数据模型: Map root = new HashMap(); root.put("user","annlee"); 下面将user变量和常量连接起来: ${"hello, ${user}!"} //使用第一种语法来连接 ${"hello, " + user + "!"} //使用+号来连接 上面的输出字符串都是hello,annlee!,可以看出这两种语法的效果完全一样.
值得注意的是,${..}只能用于文本部分,不能用于表达式,下面的代码是错误的: <#if ${isBig}>Wow!#if> <#if "${isBig}">Wow!#if> 应该写成:<#if isBig>Wow!#if>
截取子串可以根据字符串的索引来进行,截取子串时如果只指定了一个索引值,则用于取得字符串中指定索引所对应的字符;如果指定两个索引值,则返回两个索引中间的字符串子串.假如有如下数据模型: Map root = new HashMap(); root.put("book","struts2,freemarker"); 可以通过如下语法来截取子串: ${book[0]}${book[4]} //结果是su ${book[1..4]} //结果是tru
3.4 集合连接运算符
这里所说的集合运算符是将两个集合连接成一个新的集合,连接集合的运算符是+,看如下的例子: <#list ["星期一","星期二","星期三"] + ["星期四","星期五","星期六","星期天"] as x> ${x} #list> 输出结果是:星期一 星期二 星期三 星期四 星期五 星期六 星期天
3.5 Map连接运算符
Map对象的连接运算符也是将两个Map对象连接成一个新的Map对象,Map对象的连接运算符是+,如果两个Map对象具有相同的key,则右边的值替代左边的值.看如下的例子: <#assign scores = {"语文":86,"数学":78} + {"数学":87,"Java":93}> 语文成绩是${scores.语文} 数学成绩是${scores.数学} Java成绩是${scores.Java} 输出结果是: 语文成绩是86 数学成绩是87 Java成绩是93
3.6 算术运算符
FreeMarker表达式中完全支持算术运算,FreeMarker支持的算术运算符包括:+, - , * , / , % 看如下的代码: <#assign x=5> ${ x * x - 100 } ${ x /2 } ${ 12 %10 } 输出结果是: -75 2.5 2
在表达式中使用算术运算符时要注意以下几点: 1,运算符两边的运算数字必须是数字 2,使用+运算符时,如果一边是数字,一边是字符串,就会自动将数字转换为字符串再连接,如:${3 + "5"},结果是:35
使用内建的int函数可对数值取整,如: <#assign x=5> ${ (x/2)?int } ${ 1.1?int } ${ 1.999?int } ${ -1.1?int } ${ -1.999?int } 结果是:2 1 1 -1 -1
3.7 比较运算符
表达式中支持的比较运算符有如下几个: 1,=或者==:判断两个值是否相等. 2,!=:判断两个值是否不等. 3,>或者gt:判断左边值是否大于右边值 4,>=或者gte:判断左边值是否大于等于右边值 5,<或者lt:判断左边值是否小于右边值 6,<=或者lte:判断左边值是否小于等于右边值
注意:=和!=可以用于字符串,数值和日期来比较是否相等,但=和!=两边必须是相同类型的值,否则会产生错误,而且FreeMarker是精确比较,"x","x ","X"是不等的.其它的运行符可以作用于数字和日期,但不能作用于字符串,大部分的时候,使用gt等字母运算符代替>会有更好的效果,因为FreeMarker会把>解释成FTL标签的结束字符,当然,也可以使用括号来避免这种情况,如:<#if (x>y)>
3.8 逻辑运算符
逻辑运算符有如下几个: 逻辑与:&& 逻辑或:|| 逻辑非:! 逻辑运算符只能作用于布尔值,否则将产生错误
3.9 内建函数
FreeMarker还提供了一些内建函数来转换输出,可以在任何变量后紧跟?,?后紧跟内建函数,就可以通过内建函数来轮换输出变量.下面是常用的内建的字符串函数: html:对字符串进行HTML编码 cap_first:使字符串第一个字母大写 lower_case:将字符串转换成小写 upper_case:将字符串转换成大写 trim:去掉字符串前后的空白字符
下面是集合的常用内建函数 size:获取序列中元素的个数
下面是数字值的常用内建函数 int:取得数字的整数部分,结果带符号
例如: <#assign test="Tom & Jerry"> ${test?html} ${test?upper_case?html} 结果是:Tom & Jerry TOM & JERRY
3.10 空值处理运算符
FreeMarker对空值的处理非常严格,FreeMarker的变量必须有值,没有被赋值的变量就会抛出异常,因为FreeMarker未赋值的变量强制出错可以杜绝很多潜在的错误,如缺失潜在的变量命名,或者其他变量错误.这里所说的空值,实际上也包括那些并不存在的变量,对于一个Java的null值而言,我们认为这个变量是存在的,只是它的值为null,但对于FreeMarker模板而言,它无法理解null值,null值和不存在的变量完全相同.
为了处理缺失变量,FreeMarker提供了两个运算符: !:指定缺失变量的默认值 ??:判断某个变量是否存在
其中,!运算符的用法有如下两种: variable!或variable!defaultValue,第一种用法不给缺失的变量指定默认值,表明默认值是空字符串,长度为0的集合,或者长度为0的Map对象.
使用!指定默认值时,并不要求默认值的类型和变量类型相同.使用??运算符非常简单,它总是返回一个布尔值,用法为:variable??,如果该变量存在,返回true,否则返回false
3.11 运算符的优先级
FreeMarker中的运算符优先级如下(由高到低排列): 1,一元运算符:! 2,内建函数:? 3,乘除法:*, / , % 4,加减法:- , + 5,比较:> , < , >= , <= (lt , lte , gt , gte) 6,相等:== , = , != 7,逻辑与:&& 8,逻辑或:|| 9,数字范围:..
实际上,我们在开发过程中应该使用括号来严格区分,这样的可读性好,出错少
4 FreeMarker的常用指令
FreeMarker的FTL指令也是模板的重要组成部分,这些指令可实现对数据模型所包含数据的抚今迭代,分支控制.除此之外,还有一些重要的功能,也是通过FTL指令来实现的.
4.1 if指令
这是一个典型的分支控制指令,该指令的作用完全类似于Java语言中的if,if指令的语法格式如下: <#if condition>... <#elseif condition>... <#elseif condition>... <#else> ... #if>
例子如下: <#assign age=23> <#if (age>60)>老年人 <#elseif (age>40)>中年人 <#elseif (age>20)>青年人 <#else> 少年人 #if> 输出结果是:青年人 上面的代码中的逻辑表达式用括号括起来主要是因为里面有>符号,由于FreeMarker会将>符号当成标签的结束字符,可能导致程序出错,为了避免这种情况,我们应该在凡是出现这些符号的地方都使用括号.
4.2 switch , case , default , break指令
这些指令显然是分支指令,作用类似于Java的switch语句,switch指令的语法结构如下: <#switch value> <#case refValue>...<#break> <#case refValue>...<#break> <#default>... #switch>
4.3 list, break指令
list指令是一个迭代输出指令,用于迭代输出数据模型中的集合,list指令的语法格式如下: <#list sequence as item> ... #list> 上面的语法格式中,sequence就是一个集合对象,也可以是一个表达式,但该表达式将返回一个集合对象,而item是一个任意的名字,就是被迭代输出的集合元素.此外,迭代集合对象时,还包含两个特殊的循环变量: item_index:当前变量的索引值 item_has_next:是否存在下一个对象 也可以使用<#break>指令跳出迭代
例子如下: <#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as x> ${x_index + 1}.${x}<#if x_has_next>, <#if x="星期四"><#break>#if> #list>
4.4 include指令
include指令的作用类似于JSP的包含指令,用于包含指定页.include指令的语法格式如下: <#include filename [options]> 在上面的语法格式中,两个参数的解释如下: filename:该参数指定被包含的模板文件 options:该参数可以省略,指定包含时的选项,包含encoding和parse两个选项,其中encoding指定包含页面时所用的解码集,而parse指定被包含文件是否作为FTL文件来解析,如果省略了parse选项值,则该选项默认是true.
4.5 import指令
该指令用于导入FreeMarker模板中的所有变量,并将该变量放置在指定的Map对象中,import指令的语法格式如下: <#import "/lib/common.ftl" as com> 上面的代码将导入/lib/common.ftl模板文件中的所有变量,交将这些变量放置在一个名为com的Map对象中.
4.6 noparse指令
noparse指令指定FreeMarker不处理该指定里包含的内容,该指令的语法格式如下: <#noparse>...#noparse>
看如下的例子: <#noparse> <#list books as book>
${book.name} 作者:${book.author} #list> #noparse> 输出如下: <#list books as book> ${book.name} 作者:${book.author} #list>
4.7 escape , noescape指令
escape指令导致body区的插值都会被自动加上escape表达式,但不会影响字符串内的插值,只会影响到body内出现的插值,使用escape指令的语法格式如下: <#escape identifier as expression>... <#noescape>...#noescape> #escape>
看如下的代码: <#escape x as x?html> First name:${firstName} Last name:${lastName} Maiden name:${maidenName} #escape> 上面的代码等同于: First name:${firstName?html} Last name:${lastName?html} Maiden name:${maidenName?html}
escape指令在解析模板时起作用而不是在运行时起作用,除此之外,escape指令也嵌套使用,子escape继承父escape的规则,如下例子: <#escape x as x?html> Customer Name:${customerName} Items to ship; <#escape x as itemCodeToNameMap[x]> ${itemCode1} ${itemCode2} ${itemCode3} ${itemCode4} #escape> #escape> 上面的代码类似于: Customer Name:${customerName?html} Items to ship; ${itemCodeToNameMap[itemCode1]?html} ${itemCodeToNameMap[itemCode2]?html} ${itemCodeToNameMap[itemCode3]?html} ${itemCodeToNameMap[itemCode4]?html}
对于放在escape指令中所有的插值而言,这此插值将被自动加上escape表达式,如果需要指定escape指令中某些插值无需添加escape表达式,则应该使用noescape指令,放在noescape指令中的插值将不会添加escape表达式.
4.8 assign指令
assign指令在前面已经使用了多次,它用于为该模板页面创建或替换一个顶层变量,assign指令的用法有多种,包含创建或替换一个顶层变量,或者创建或替换多个变量等,它的最简单的语法如下:<#assign name=value [in namespacehash]>,这个用法用于指定一个名为name的变量,该变量的值为value,此外,FreeMarker允许在使用assign指令里增加in子句,in子句用于将创建的name变量放入namespacehash命名空间中.
assign指令还有如下用法:<#assign name1=value1 name2=value2 ... nameN=valueN [in namespacehash]>,这个语法可以同时创建或替换多个顶层变量,此外,还有一种复杂的用法,如果需要创建或替换的变量值是一个复杂的表达式,则可以使用如下语法格式:<#assign name [in namespacehash]>capture this#assign>,在这个语法中,是指将assign指令的内容赋值给name变量.如下例子: <#assign x> <#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as n> ${n} #list> #assign> ${x} 上面的代码将产生如下输出:星期一 星期二 星期三 星期四 星期五 星期六 星期天
虽然assign指定了这种复杂变量值的用法,但是我们也不要滥用这种用法,如下例子:<#assign x>Hello ${user}!#assign>,以上代码改为如下写法更合适:<#assign x="Hello ${user}!">
4.9 setting指令
该指令用于设置FreeMarker的运行环境,该指令的语法格式如下:<#setting name=value>,在这个格式中,name的取值范围包含如下几个: locale:该选项指定该模板所用的国家/语言选项 number_format:指定格式化输出数字的格式 boolean_format:指定两个布尔值的语法格式,默认值是true,false date_format,time_format,datetime_format:指定格式化输出日期的格式 time_zone:设置格式化输出日期时所使用的时区
4.10 macro , nested , return指令
macro可以用于实现自定义指令,通过使用自定义指令,可以将一段模板片段定义成一个用户指令,使用macro指令的语法格式如下: <#macro name param1 param2 ... paramN> ... <#nested loopvar1, loopvar2, ..., loopvarN> ... <#return> ... #macro> 在上面的格式片段中,包含了如下几个部分: name:name属性指定的是该自定义指令的名字,使用自定义指令时可以传入多个参数 paramX:该属性就是指定使用自定义指令时报参数,使用该自定义指令时,必须为这些参数传入值 nested指令:nested标签输出使用自定义指令时的中间部分 nested指令中的循环变量:这此循环变量将由macro定义部分指定,传给使用标签的模板 return指令:该指令可用于随时结束该自定义指令.
看如下的例子: <#macro book> //定义一个自定义指令 j2ee #macro> <@book /> //使用刚才定义的指令 上面的代码输出结果为:j2ee
在上面的代码中,可能很难看出自定义标签的用处,因为我们定义的book指令所包含的内容非常简单,实际上,自定义标签可包含非常多的内容,从而可以实现更好的代码复用.此外,还可以在定义自定义指令时,为自定义指令指定参数,看如下代码: <#macro book booklist> //定义一个自定义指令booklist是参数 <#list booklist as book> ${book} #list> #macro> <@book booklist=["spring","j2ee"] /> //使用刚刚定义的指令 上面的代码为book指令传入了一个参数值,上面的代码的输出结果为:spring j2ee
不仅如此,还可以在自定义指令时使用nested指令来输出自定义指令的中间部分,看如下例子: <#macro page title>
FreeMarker示例页面 - ${title?html} ${title?html} <#nested> //用于引入用户自定义指令的标签体 #macro> 上面的代码将一个HTML页面模板定义成一个page指令,则可以在其他页面中如此page指令: <#import "/common.ftl" as com> //假设上面的模板页面名为common.ftl,导入页面 <@com.page title="book list"> spring j2ee @com.page >
从上面的例子可以看出,使用macro和nested指令可以非常容易地实现页面装饰效果,此外,还可以在使用nested指令时,指定一个或多个循环变量,看如下代码: <#macro book> <#nested 1> //使用book指令时指定了一个循环变量值 <#nested 2> #macro> <@book ;x> ${x} .图书@book > 当使用nested指令传入变量值时,在使用该自定义指令时,就需要使用一个占位符(如book指令后的;x).上面的代码输出文本如下: 1 .图书 2 .图书
在nested指令中使用循环变量时,可以使用多个循环变量,看如下代码: <#macro repeat count> <#list 1..count as x> //使用nested指令时指定了三个循环变量 <#nested x, x/2, x==count> #list> #macro> <@repeat count=4 ; c halfc last> ${c}. ${halfc}<#if last> Last! #if> @repeat > 上面的输出结果为: 1. 0.5 2. 1 3. 1.5 4. 2 Last;
return指令用于结束macro指令,一旦在macro指令中执行了return指令,则FreeMarker不会继续处理macro指令里的内容,看如下代码: <#macro book> spring <#return> j2ee #macro> <@book /> 上面的代码输出:spring,而j2ee位于return指令之后,不会输出.
if, else, elseif switch, case, default, break list, break include Import compress escape, noescape assign global setting macro, nested, return t, lt, rt 3一些常用方法或注意事项 表达式转换类 数字循环 对浮点取整数 给变量默认值 判断对象是不是null 常用格式化日期 添加全局共享变量数据模型 直接调用java对象的方法 字符串处理(内置方法) 在模板里对sequences和hashes初始化 注释标志 sequences内置方法 hashes内置方法 4 freemarker在web开发中注意事项 web中常用的几个对象 view中值的搜索顺序 在模板里ftl里使用标签 如何初始化共享变量 与webwork整合配置 5高级方法 自定义方法 自定义 Transforms
1概念 最常用的3个概念 sequence 序列,对应java里的list、数组等非键值对的集合 hash 键值对的集合 namespace 对一个ftl文件的引用,利用这个名字可以访问到该ftl文件的资源
2指令 if, else, elseif 语法 <#if condition> ... <#elseif condition2> ... <#elseif condition3> ... ... <#else> ... #if> 用例 <#if x = 1> x is 1 #if>
<#if x = 1> x is 1 <#else> x is not 1 #if>
switch, case, default, break 语法 <#switch value> <#case refValue1> ... <#break> <#case refValue2> ... <#break> ... <#case refValueN> ... <#break> <#default> ... #switch>
用例 字符串 <#switch being.size> <#case "small"> This will be processed if it is small <#break> <#case "medium"> This will be processed if it is medium <#break> <#case "large"> This will be processed if it is large <#break> <#default> This will be processed if it is neither #switch> 数字 <#switch x> <#case x = 1> 1 <#case x = 2> 2 <#default> d #switch>
如果x=1 输出 1 2, x=2输出 2, x=3 输出d
list, break 语法 <#list sequence as item> ... <#if item = "spring"><#break>#if> ... #list> 关键字 item_index:是list当前值的下标 item_has_next:判断list是否还有值
用例 <#assign seq = ["winter", "spring", "summer", "autumn"]> <#list seq as x> ${x_index + 1}. ${x}<#if x_has_next>,#if> #list>
输出 1. winter, 2. spring, 3. summer, 4. autumn
include 语法 <#include filename> or <#include filename options> options包含两个属性 encoding=”GBK” 编码格式 parse=true 是否作为ftl语法解析,默认是true,false就是以文本方式引入.注意在ftl文件里布尔值都是直接赋值的如parse=true,而不是parse=”true” 用例 /common/copyright.ftl包含内容 Copyright 2001-2002 ${me} All rights reserved. 模板文件 <#assign me = "Juila Smith">
Some test Yeah.
<#include "/common/copyright.ftl" encoding=”GBK”> 输出结果 Some test Yeah.
Copyright 2001-2002 Juila Smith All rights reserved.
Import 语法 <#import path as hash> 类似于java里的import,它导入文件,然后就可以在当前文件里使用被导入文件里的宏组件
用例
假设mylib.ftl里定义了宏copyright那么我们在其他模板页面里可以这样使用 <#import "/libs/mylib.ftl" as my>
<@my.copyright date="1999-2002"/>
"my"在freemarker里被称作namespace
compress 语法 <#compress> ... #compress> 用来压缩空白空间和空白的行 用例 <#assign x = " moo \n\n "> (<#compress> 1 2 3 4 5 ${moo} test only
I said, test only
#compress>) 输出 (1 2 3 4 5 moo test only I said, test only) escape, noescape 语法 <#escape identifier as expression> ... <#noescape>...#noescape> ... #escape> 用例 主要使用在相似的字符串变量输出,比如某一个模块的所有字符串输出都必须是html安全的,这个时候就可以使用该表达式 <#escape x as x?html> First name: ${firstName} <#noescape>Last name: ${lastName}#noescape> Maiden name: ${maidenName} #escape> 相同表达式 First name: ${firstName?html} Last name: ${lastName } Maiden name: ${maidenName?html} assign 语法 <#assign name=value> or <#assign name1=value1 name2=value2 ... nameN=valueN> or <#assign same as above... in namespacehash> or <#assign name> capture this #assign> or <#assign name in namespacehash> capture this #assign> 用例 生成变量,并且给变量赋值 给seasons赋予序列值 <#assign seasons = ["winter", "spring", "summer", "autumn"]>
给变量test加1 <#assign test = test + 1>
给my namespage 赋予一个变量bgColor,下面可以通过my.bgColor来访问这个变量 <#import "/mylib.ftl" as my> <#assign bgColor="red" in my>
将一段输出的文本作为变量保存在x里 下面的阴影部分输出的文本将被赋值给x <#assign x> <#list 1..3 as n> ${n} <@myMacro /> #list> #assign> Number of words: ${x?word_list?size} ${x}
<#assign x>Hello ${user}!#assign> error <#assign x=” Hello ${user}!”> true
同时也支持中文赋值,如: <#assign 语法> java #assign> ${语法} 打印输出: java global 语法 <#global name=value> or <#global name1=value1 name2=value2 ... nameN=valueN> or <#global name> capture this #global>
全局赋值语法,利用这个语法给变量赋值,那么这个变量在所有的namespace中是可见的,如果这个变量被当前的assign语法覆盖 如<#global x=2> <#assign x=1> 在当前页面里x=2将被隐藏,或者通过${.global.x}来访问
setting 语法 <#setting name=value> 用来设置整个系统的一个环境 locale number_format boolean_format date_format, time_format, datetime_format time_zone classic_compatible 用例 假如当前是匈牙利的设置,然后修改成美国 ${1.2} <#setting locale="en_US"> ${1.2} 输出 1,2 1.2 因为匈牙利是采用“,”作为十进制的分隔符,美国是用“.”
macro, nested, return 语法
<#macro name param1 param2 ... paramN> ... <#nested loopvar1, loopvar2, ..., loopvarN> ... <#return> ... #macro> 用例 <#macro test foo bar="Bar" baaz=-1> Test text, and the params: ${foo}, ${bar}, ${baaz} #macro> <@test foo="a" bar="b" baaz=5*5-2/> <@test foo="a" bar="b"/> <@test foo="a" baaz=5*5-2/> <@test foo="a"/> 输出 Test text, and the params: a, b, 23 Test text, and the params: a, b, -1 Test text, and the params: a, Bar, 23 Test text, and the params: a, Bar, -1 定义循环输出的宏 <#macro list title items>
${title?cap_first}:
<#list items as x> ${x?cap_first} #list> #macro> <@list items=["mouse", "elephant", "python"] title="Animals"/> 输出结果 Animals:
包含body的宏 <#macro repeat count> <#list 1..count as x> <#nested x, x/2, x==count> #list> #macro> <@repeat count=4 ; c halfc last> ${c}. ${halfc}<#if last> Last!#if> @repeat > 输出 1. 0.5 2. 1 3. 1.5 4. 2 Last!
t, lt, rt 语法 <#t> 去掉左右空白和回车换行
<#lt>去掉左边空白和回车换行
<#rt>去掉右边空白和回车换行
<#nt>取消上面的效果
3一些常用方法或注意事项
表达式转换类 ${expression}计算expression并输出 #{ expression }数字计算#{ expression ;format}安格式输出数字format为M和m M表示小数点后最多的位数,m表示小数点后最少的位数如#{121.2322;m2M2}输出121.23
数字循环 1..5 表示从1到5,原型number..number 对浮点取整数 ${123.23?int} 输出123 给变量默认值 ${var?default(“hello world ”)?html}如果var is null那么将会被hello world 替代
判断对象是不是null <#if mouse?exists> Mouse found <#else> 也可以直接${mouse?if_exists})输出布尔形 常用格式化日期 openingTime必须是Date型,详细查看freemarker文档 Reference->build-in referece->build-in for date
${openingTime?date} ${openingTime?date_time} ${openingTime?time}
添加全局共享变量数据模型 在代码里的实现 cfg = Configuration.getDefaultConfiguration(); cfg.setSharedVariable("global", "you good"); 页面实现可以通过global指令,具体查看指令里的global部分 直接调用java对象的方法 ${object.methed(args)}
字符串处理(内置方法) html安全输出 “abc
sdfsf”?html 返回安全的html输出,替换掉html代码 xml安全输出 var?xml substring的用法 <#assign user=”hello jeen”> ${user[0]}${user[4]} ${user[1..4]} 输出 : ho ello 类似String.split的用法 “abc;def;ghi”?split(“;”)返回sequence 将字符串按空格转化成sequence,然后取sequence的长度 var?word_list 效果同 var?split(“ ”) var?word_list?size
取得字符串长度 var?length
大写输出字符 var?upper_case
小写输出字符 var?lower_case
首字符大写 var?cap_first
首字符小写 var?uncap_first
去掉字符串前后空格 var?trim
每个单词的首字符大写 var?capitalize
类似String.indexof: “babcdabcd”?index_of(“abc”) 返回1 “babcdabcd”?index_of(“abc”,2) 返回5 类似String.lastIndexOf last_index_of和String.lastIndexOf类似,同上
下面两个可能在代码生成的时候使用(在引号前加”\”) j_string: 在字符串引号前加”\” <#assign beanName = 'The "foo" bean.'> String BEAN_NAME = "${beanName?j_string}"; 打印输出: String BEAN_NAME = "The \"foo\" bean."; js_string: <#assign user = "Big Joe's \"right hand\"."> 打印输出 alert("Welcome Big Joe\'s \"right hand\"!");
替换字符串 replace ${s?replace(‘ba’, ‘XY’ )} ${s?replace(‘ba’, ‘XY’ , ‘规则参数’)}将s里的所有的ba替换成xy 规则参数包含: i r m s c f 具体含义如下: · i: 大小写不区分. · f: 只替换第一个出现被替换字符串的字符串 · r: XY是正则表达式 · m: Multi-line mode for regular expressions. In multi-line mode the expressions ^ and $ match just after or just before, respectively, a line terminator or the end of the string. By default these expressions only match at the beginning and the end of the entire string. · s: Enables dotall mode for regular expressions (same as Perl singe-line mode). In dotall mode, the expression . matches any character, including a line terminator. By default this expression does not match line terminators. · c: Permits whitespace and comments in regular expressions.
在模板里对sequences和hashes初始化 sequences
1. [“you”,”me”,”he”] 2. 1..100 3. [ {“Akey”:”Avalue”},{“Akey1”:”Avalue1”}, {“Bkey”:”Bvalue”},{“Bkey1”:”Bvalue1”}, ]
hashes {“you”:”a”,”me”:”b”,”he”:”c”}
注释标志 <#-- 这里是注释 --> 旧版本的freemarker采用的是<#comment> 注释 #comment>方法
sequences内置方法 sequence?first 返回sequence的第一个值;前提条件sequence不能是null sequence?last 返回sequence最后一个值 sequence?reverse 反转sequence的值 sequence?size 返回sequence的大小 sequence?sort 对sequence按里面的对象toString()的结果进行排序 sequence?sort_by(value) 对sequence 按里面的对象的属性value进行排序 如: sequence里面放入的是10 个user对象,user对象里面包含name,age等属性 sequence?sort_by(name) 表示所有的user按user.name进行排序 hashes内置方法 hash?keys 返回hash里的所有keys, 返回结果类型sequence hash?values 返回hash里的所有value, 返回结果类型sequence 4 freemarker在web开发中注意事项 freemarker与webwork整合 web中常用的几个对象 Freemarker的ftl文件中直接使用内部对象: ${Request ["a"]} ${RequestParameters["a"]} ${Session ["a"]} ${Application ["a"]} ${JspTaglibs ["a"]}
与webwork整合之后 通过配置的servlet 已经把request,session等对象置入了数据模型中 在view中存在下面的对象 我们可以在ftl中${req}来打印req对象 · req - the current HttpServletRequest · res - the current HttpServletResponse · stack - the current OgnlValueStack · ognl - the OgnlTool instance · webwork - an instance of FreemarkerWebWorkUtil · action - the current WebWork action · exception - optional the Exception instance, if the view is a JSP exception or Servlet exception view view中值的搜索顺序 ${name}将会以下面的顺序查找name值 · freemarker variables · value stack · request attributes · session attributes · servlet context attributes 在模板里ftl里使用标签 注意,如果标签的属性值是数字,那么必须采用nubmer=123方式给属性赋值 JSP页面 <%@page contentType="text/html;charset=ISO-8859-2" language="java"%> <%@taglib uri="/WEB-INF/struts-html.tld" prefix="html"%> <%@taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
Keyword: Exclude: 模板ftl页面 <#assign html=JspTaglibs["/WEB-INF/struts-html.tld"]> <#assign bean=JspTaglibs["/WEB-INF/struts-bean.tld"]>
<@bean.message key="welcome.title"/> <@html.errors/> <@html.form action="/query"> Keyword: <@html.text property="keyword"/> Exclude: <@html.text property="exclude"/> <@html.submit value="Send"/> @html.form >
如何初始化共享变量 1. 初始化全局共享数据模型 freemark在web上使用的时候对共享数据的初始化支持的不够,不能在配置初始化的时候实现,而必须通过ftl文件来初始化全局变量。这是不能满主需求的,我们需要在servlet init的时候留出一个接口来初始化系统的共享数据 具体到和webwork整合,因为本身webwork提供了整合servlet,如果要增加全局共享变量,可以通过修改com.opensymphony.webwork.views.freemarker.FreemarkerServlet来实现,我们可以在这个servlet初始化的时候来初始化全局共享变量 与webwork整合配置 配置web.xml freemarker com.opensymphony.webwork.views.freemarker.FreemarkerServlet TemplatePath / NoCache true ContentType text/html template_update_delay 0 default_encoding GBK number_format 0.########## 1 freemarker *.ftl
5高级方法 自定义方法 ${timer("yyyy-MM-dd H:mm:ss", x)} ${timer("yyyy-MM-dd ", x)}
在模板中除了可以通过对象来调用方法外(${object.methed(args)})也可以直接调用java实现的方法,java类必须实现接口TemplateMethodModel的方法exec(List args). 下面以把毫秒的时间转换成按格式输出的时间为例子 public class LongToDate implements TemplateMethodModel { public TemplateModel exec(List args) throws TemplateModelException { SimpleDateFormat mydate = new SimpleDateFormat((String) args.get(0))); return mydate.format(new Date(Long.parseLong((String)args.get(1))); } } 将LongToDate对象放入到数据模型中 root.put("timer", new IndexOfMethod()); ftl模板里使用 <#assign x = "123112455445"> ${timer("yyyy-MM-dd H:mm:ss", x)} ${timer("yyyy-MM-dd ", x)}
输出 2001-10-12 5:21:12 2001-10-12
自定义 Transforms 实现自定义的<@transform>文本或表达式@transform >的功能,允许对中间的最终文本进行解析转换
例子:实现<@upcase>str@upcase > 将str转换成STR 的功能
代码如下: 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() { } } } 然后将此对象put到数据模型中 root.put("upcase", new UpperCaseTransform());
在view(ftl)页面中可以如下方式使用
<@upcase> hello world @upcase >
打印输出: HELLO WORLD
你可能感兴趣的:(一篇很全面的freemarker教程)
嵌入式系统测试必备:9大理由解析报告与可追溯性的重要性(附工具推荐TESSY)
在嵌入式系统的软件测试项目中,报告和可追溯性至关重要,原因有多个。它们是确保嵌入式系统可靠、合规且高质量的基础。报告和可追溯性不仅支持有效的项目管理,还促进了维护和调试,并为审计及持续改进工作提供了必要的文档支持。理由1:合规性嵌入式系统常用于汽车、航空航天、医疗设备和工业控制系统等关键应用领域。这些行业受到严格的法规和标准约束(例如ISO26262、DO-178C、IEC62304)。全面的报告
《java性能调优》2.Stream如何提高遍历集合效率
just_one_wk
java性能调优
在Java8中,Collection新增了两个流方法,分别是Stream()和parallelStream()。什么是Stream?在Java8之前,我们通常是通过for循环或者Iterator迭代来重新排序合并数据,又或者通过重新定义Collections.sorts的Comparator方法来实现,这两种方式对于大数据量系统来说,效率并不是很理想。Java8中添加了一个新的接口类Stream,
【赵渝强老师】达梦数据库的归档模式
数据库信创
达梦数据库的备份与恢复都需要使用到重做日志文件。在默认的情况下,达梦数据库采用的非归档模式。通过执行下面的语句可以查看当前数据库实例的日志模式。SQL>selectarch_modefromv$database;#输出的信息如下:行号ARCH_MODE-------------------1N#提示:这里输出的N表示的是非归档模式。由于在非归档模式下,重做日志文件会发生覆盖的情况,从而造成数据的丢
从过拟合到强化学习:机器学习核心知识全解析
吴师兄大模型
0基础实现机器学习入门到精通 机器学习 人工智能 过拟合 强化学习 python LLM scikit-learn
Langchain系列文章目录01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南02-玩转LangChainMemory模块:四种记忆类型详解及应用场景全覆盖03-全面掌握LangChain:从核心链条构建到动态任务分配的实战指南04-玩转LangChain:从文档加载到高效问答系统构建的全程实战05-玩转LangChain:深度评估问答系统的三种高效方法(示例生成、手
DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加列宽调整功能,示例Table14_07带分页的固定表头表格
宝码香车
# DeepSeek javascript 前端 vue.js ecmascript DeepSeek
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦目录DeepSeek助力Vue3开发:打造丝滑的表格(Table)之添加列宽调整功能,示例Table14_07带分页的固定表头表格页面效果组件代码代码测试测试代码正常跑通,附其他基本代码编写路由src\router\index.js编写展示入口s
DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加列宽调整功能,示例Table14_04带选择框的固定表头表格
宝码香车
# DeepSeek javascript 前端 vue.js ecmascript DeepSeek deepSeek deepseek
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦目录DeepSeek助力Vue3开发:打造丝滑的表格(Table)之添加列宽调整功能,示例Table14_04带选择框的固定表头表格页面效果组件代码代码测试测试代码正常跑通,附其他基本代码编写路由src\router\index.js编写展示入口
DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加列宽调整功能,示例Table14_01基础固定表头示例
宝码香车
# DeepSeek javascript 前端 vue.js ecmascript DeepSeek
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦目录DeepSeek助力Vue3开发:打造丝滑的表格(Table)之添加列宽调整功能,示例Table14_01基础固定表头示例页面效果组件代码测试代码正常跑通,附其他基本代码编写路由src\router\index.js编写展示入口src\App
DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)示例3: 行选择
宝码香车
# DeepSeek vue.js javascript ecmascript 前端 DeepSeek
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦目录DeepSeek助力Vue3开发:打造丝滑的表格(Table)示例3:行选择前言页面效果指令输入定义属性数据相关样式与布局相关功能相关定义事件其他think组件代码代码测试示例3,整理后主要代码定义组件\src\views\TableView
MATAB学习笔记2
好大一口果汁
MATLAB 学习 笔记 算法
1.多项式拟合>>p=polyfit(DateNum,Pclose,1);%多项式拟合>>value=p(1)%将斜率赋值给value,作为股票的价值value=0.1212代码分析:%后面的内容是注释,ployfit()有三个参数,第三个参数表示多项式的阶数,也就是最高次数。比如:第三个参数为1,说明为1次项,即一次函数,第三个参数为你要拟合的阶数,一阶直线拟合,二阶抛物线拟合,并非阶次越高越好
Azure Kubernetes Service (AKS) Workshop 教程
黎玫洵Errol
AzureKubernetesService(AKS)Workshop教程aksworkshopAzureKubernetesService(AKS)workshopwebsitecontent项目地址:https://gitcode.com/gh_mirrors/ak/aksworkshop1、项目介绍AzureKubernetesService(AKS)Workshop是一个开源项目,旨在帮助
【DevOps】Azure Kubernetes 服务 (AKS) 集群中安装ArgoCD
小涵
Azure云企业实践分享 DevOps企业级项目实战 devops azure kubernetes docker argocd 运维
【DevOps】AzureKubernetes服务(AKS)集群中安装ArgoCD推荐超级课程:本地离线DeepSeekAI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录【DevOps】AzureKubernetes服务(AKS)集群中安装ArgoCD安装步骤如下:ArgoCD是一个声明式的GitOps持续交付工具,用于Kube
自动语音识别(ASR)模型全览
u013250861
# 语音识别 人工智能
以下为截至2024年底主流ASR模型的详细列表,涵盖传统模型、端到端模型、开源框架及商业解决方案,按技术类型分类整理,并标注适用场景:一、传统混合模型(GMM/HMM、DNN/HMM)GMM/HMM公开时间:1980年代参数量:百万级(依赖状态数)特点:基于高斯混合模型(GMM)与隐马尔可夫模型(HMM)结合,需手工对齐音素状态。适用场景:早期电话语音识别(嵌入式设备)、孤立词识别(工业控制终端)
【开源所有代码-全在线智能音箱】树莓派智能音箱,自定义唤醒词,大模型LLM GPT对话
南七小僧
服务器开发 人工智能 AI技术产品经理 智能音箱 gpt
安装sounddevicepipinstallsounddevice安装portAudiosudoapt-getinstalllibportaudio2sudoapt-getinstalllibasound-devsudoapt-getinstallportaudio.devsudoapt-getinstallpython3-pyaudiopipinstallpyaudio安装wavepipins
一篇文章介绍清楚什么是Web自动化智能体?
霍格沃兹测试开发学社
人工智能 前端 自动化 运维 人工智能 deepseek 语言模型 开源
Web自动化正逐渐成为提升效率、降低成本的利器。无论是数据抓取、表单填写,还是复杂的业务流程自动化,Web自动化智能体都能轻松应对。那么,这些智能体是如何工作的?它们的核心元素有哪些?今天,我们就来一探究竟!大模型智能体的“大脑”Web自动化智能体的核心驱动力来自于大模型(如ChatGPT、Claude、Ollama)。这些大模型赋予了智能体强大的自然语言理解和任务规划能力。任务理解:智能体能够准
2021-05-25
张辣鸡
爬虫记录 python 爬虫
解决12306抢票系统弹出来的弹窗问题应为疫情原因进入12306网站登陆界面弹出来这样一个界面进入登陆界面的网站,把鼠标放在确定的位置右键点击检查,找到#我把它放在另一个函数中,这样调用就可以了defclick_ok1(self):bounce_button=driver.find_element_by_css_selector(".btn.btn-primary.ok")bounce_butto
【云原生之kubernetes实战】在k8s环境中高效部署minio对象存储(详细教程)
江湖有缘
云原生 kubernetes 容器
【云原生之kubernetes实战】在k8s环境中高效部署minio对象存储(详细教程)前言一、minio介绍1.1MinIO简介1.2主要特点1.3主要使用场景二、相关知识介绍2.1本次实践存储介绍2.2k8s存储介绍三、本次实践介绍3.1本次实践简介3.2本次环境规划3.3部署前需准备工作四、检查k8s环境4.1检查工作节点状态4.2检查系统pod状态五、部署minio对象存储5.1编辑min
C++内存管理——unique_ptr
HIT_055
c++ c++11
1.概述本想将unique_ptr,shared_ptr和weak_ptr写在同一篇文章中,无奈越(废)写(话)越(连)长(篇),本着不给自己和读者太大压力的原则,最终决定分为三篇去描述它们(不是恶意凑文章数哦)。本篇文章主要描述了unique_ptr,在此之前先给出了auto_ptr的介绍,废话不说,直入正题。2.auto_ptrauto_ptr是在C++98中引入的,在C++17中被移除掉。它
Python 进程和线程-进程 vs. 线程
赔罪
Python 系统学习 python 开发语言
目录ThreadLocal小结进程vs.线程线程切换计算密集型vs.IO密集型异步IOThreadLocal在多线程环境下,每个线程都有自己的数据。一个线程使用自己的局部变量比使用全局变量好,因为局部变量只有线程自己能看见,不会影响其他线程,而全局变量的修改必须加锁。但是局部变量也有问题,就是在函数调用的时候,传递起来很麻烦:defprocess_student(name):std=Student
ElementUI元件库与后台模板页面(支持Axure8及9)
贡驰赞Powerful
ElementUI元件库与后台模板页面(支持Axure8及9)【下载地址】ElementUI元件库与后台模板页面支持Axure8及9本仓库提供了一个全面的资源文件,包含ElementUI元件库及后台模板页面,支持Axure8及9版本。该资源文件旨在帮助设计师和产品经理快速构建高保真原型,提升工作效率项目地址:https://gitcode.com/open-source-toolkit/50b64
机器学习的下一个前沿是因果推理吗?——探索机器学习的未来方向!
真智AI
人工智能 机器学习
机器学习的进化:从预测到因果推理机器学习凭借强大的预测能力,已经彻底改变了多个行业。然而,要实现真正的突破,机器学习还需要克服实践和计算上的挑战,特别是在因果推理方面的应用。未来,因果推理或许将成为推动机器学习发展的新前沿。什么是因果推理,它如何与机器学习相关?如果你和我一样没有数学背景,你可能会好奇“因果推理”到底意味着什么?它与机器学习又有什么关系?当我刚开始学习机器学习时,第一次听到“因果推
深度好文 图解 RocketMQ 的系统架构
橘野禾
系统架构 kafka java 分布式 后端
今天给大家分享一篇学习RocketMQ系统架构核心知识点的梳理和总结,在讲解时力求精简、通俗易懂,通过图解来给正在学习RocketMQ的小伙伴带来帮助。RocketMQ是阿里巴巴的分布式消息中间件,在2012年开源,在2017年成为Apache顶级项目。1集群架构RocketMQ的集群架构如下图:从上图可以看到,整个集群中有四个角色:NameServer集群、Broker主从集群、Producer
黑客攻防从入门到精通(第一篇:认识黑客)
晓生夜梦
# 黑客攻防书籍学习笔记 信息安全
1.黑客:白帽,灰帽,黑帽(骇客)2.黑客术语:肉鸡(可以随意被黑客控制的计算机),木马(伪装成正常程序),网页木马(有人访问时,利用对方系统或者浏览器的漏洞自动将配置好木马的服务下载到访问者的计算机上自动执行),挂马,后门(重新控制计算机)IPC$,shell,webshell,溢出,注入,注入点免杀(用一些技术修改程序,让它逃过杀毒软件查杀),加壳花指令(让汇编语言进行一些跳转——就比如杀毒软
## VMware 虚拟机保姆级教程:从零开始玩转虚拟化
一只联想小新15呀~
运维开发
虚拟化技术已经成为现代计算不可或缺的一部分,而VMware作为虚拟化领域的领导者,其产品VMwareWorkstationPlayer和VMwareWorkstationPro更是深受广大用户喜爱。无论你是想体验不同操作系统,还是搭建测试环境,VMware都能满足你的需求。本教程将带你从零开始,一步步学习如何使用VMware虚拟机。**一、准备工作**1.**下载VMwareWorkstation
Web安全攻防入门教程——hvv行动详解
白帽子黑客罗哥
web安全 安全 网络安全 python java
Web安全攻防入门教程Web安全攻防是指在Web应用程序的开发、部署和运行过程中,保护Web应用免受攻击和恶意行为的技术与策略。这个领域不仅涉及防御措施的实现,还包括通过渗透测试、漏洞挖掘和模拟攻击来识别潜在的安全问题。本教程将带你入门Web安全攻防的基础概念、常见攻击类型、防御技术以及一些实战方法。一、Web安全基础Web应用安全的三大核心目标(CIA三原则)机密性(Confidentialit
《黑客攻防从入门到精通:工具篇》全15章万字深度总结——从工具解析到实战攻防,构建完整网络安全知识体系
予安灵
黑客技术 web安全 安全 系统安全 网络安全 安全架构 网络攻击模型 黑客工具链
目录一、书籍核心逻辑与学习路径二、核心模块与工具深度解析模块1:信息收集与网络扫描模块2:渗透测试与漏洞利用模块3:密码攻防与身份认证模块4:恶意程序攻防模块5:网络追踪与反追踪模块6:系统加固与数据防护三、工具链实战方法论第一章:黑客必备小工具第二章:扫描与嗅探工具第三章:注入工具(诸如工具)第四章:密码攻防工具第五章:病毒攻防常用工具第六章:木马攻防常用工具第七章:网游与网吧攻防工具第八章:黑
如何设计一个高并发的秒杀架构?
老程不秃
数据结构 Java 后端 架构 java 数据结构 程序人生 spring
写在前面高并发下如何设计秒杀系统?这是一个高频面试题。这个问题看似简单,但是里面的水很深,它考查的是高并发场景下,从前端到后端多方面的知识。秒杀一般出现在商城的促销活动中,指定了一定数量(比如:10个)的商品(比如:手机),以极低的价格(比如:0.1元),让大量用户参与活动,但只有极少数用户能够购买成功。这类活动商家绝大部分是不赚钱的,说白了是找个噱头宣传自己。虽说秒杀只是一个促销活动,但对技术要
scanf 没有(不加)取地址符 & 的情况
陌路物是人非
c语言
for(inti=1;i<=n;i++)scanf("%d",a+i);之前看到过这种不加取地址符的scanf刚开始很疑惑,觉得有问题,但我学了指针之后就恍然大悟了。首先这个a不是变量,而是一个数组,a代表着数组名同时也是这个数组的首地址即&a[0]。其次a+i代表的就是数组中下一个元素的地址即&a[0+i]。因为本身已经就是地址了,所以就不用取地址
3.2 Spring Boot单元测试:Mockito+JUnit5全覆盖策略
Sendingab
Spring boot 从入门到精通 零基础7天精通Spring Boot spring boot 单元测试 log4j
markdown#SpringBoot单元测试:Mockito+JUnit5全覆盖策略##引言在持续交付的敏捷开发中,**单元测试覆盖率**是衡量代码质量的核心指标。SpringBoot项目如何通过`JUnit5`+`Mockito`实现
2025年移动端技术探索-DeepSeek这么说
轻口味
移动端 移动端 Android HarmonyOS HarmonyOSNext iOS AI DeepSeek
随着移动互联网的逐步成熟,从增量市场向存量市场过度,对于开发的需求量大减,技术层面和业务层面的的需求量都很乏力。而且随着AI的发展,知识门槛基本消失,技能门槛也在缩短,从移动互联网向AI时代过度期间,更加比拼业务比拼创意,希望用AI重新改造某个行业。移动端方向整个24年最大的需求量是鸿蒙,2024年被称为“原生鸿蒙关键年”,华为联合头部企业(如中国移动、美团、百度等)加速构建独立生态,预计2024
主流开源大模型能力对比矩阵
时光旅人01号
人工智能 开源 python 深度学习 pytorch
模型名称核心优势主要局限Llama2/3✅多语言生态完善✅Rotary位置编码✅GQA推理加速⚠️数据时效性差⚠️隐私保护不足Qwen✅千亿参数规模✅中文语境优化✅复杂文本生成⚠️需高性能硬件⚠️领域知识需二次训练ChatGLM-3✅多轮对话支持✅中英双语流畅✅对话记忆优秀⚠️计算资源消耗大⚠️长文本易发散DeepSeek✅代码注释生成✅技术文档规范✅全流程方案生成⚠️逻辑错误较多⚠️数据更新延迟
jvm调优总结(从基本概念 到 深度优化)
oloz
java jvm jdk 虚拟机 应用服务器
JVM参数详解:http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html
Java虚拟机中,数据类型可以分为两类:基本类型和引用类型。基本类型的变量保存原始值,即:他代表的值就是数值本身;而引用类型的变量保存引用值。“引用值”代表了某个对象的引用,而不是对象本身,对象本身存放在这个引用值所表示的地址的位置。
【Scala十六】Scala核心十:柯里化函数
bit1129
scala
本篇文章重点说明什么是函数柯里化,这个语法现象的背后动机是什么,有什么样的应用场景,以及与部分应用函数(Partial Applied Function)之间的联系 1. 什么是柯里化函数
A way to write functions with multiple parameter lists. For instance
def f(x: Int)(y: Int) is a
HashMap
dalan_123
java
HashMap在java中对很多人来说都是熟的;基于hash表的map接口的非同步实现。允许使用null和null键;同时不能保证元素的顺序;也就是从来都不保证其中的元素的顺序恒久不变。
1、数据结构
在java中,最基本的数据结构无外乎:数组 和 引用(指针),所有的数据结构都可以用这两个来构造,HashMap也不例外,归根到底HashMap就是一个链表散列的数据
Java Swing如何实时刷新JTextArea,以显示刚才加append的内容
周凡杨
java 更新 swing JTextArea
在代码中执行完textArea.append("message")后,如果你想让这个更新立刻显示在界面上而不是等swing的主线程返回后刷新,我们一般会在该语句后调用textArea.invalidate()和textArea.repaint()。
问题是这个方法并不能有任何效果,textArea的内容没有任何变化,这或许是swing的一个bug,有一个笨拙的办法可以实现
servlet或struts的Action处理ajax请求
g21121
servlet
其实处理ajax的请求非常简单,直接看代码就行了:
//如果用的是struts
//HttpServletResponse response = ServletActionContext.getResponse();
// 设置输出为文字流
response.setContentType("text/plain");
// 设置字符集
res
FineReport的公式编辑框的语法简介
老A不折腾
finereport 公式 总结
FINEREPORT用到公式的地方非常多,单元格(以=开头的便被解析为公式),条件显示,数据字典,报表填报属性值定义,图表标题,轴定义,页眉页脚,甚至单元格的其他属性中的鼠标悬浮提示内容都可以写公式。
简单的说下自己感觉的公式要注意的几个地方:
1.if语句语法刚接触感觉比较奇怪,if(条件式子,值1,值2),if可以嵌套,if(条件式子1,值1,if(条件式子2,值2,值3)
linux mysql 数据库乱码的解决办法
墙头上一根草
linux mysql 数据库乱码
linux 上mysql数据库区分大小写的配置
lower_case_table_names=1 1-不区分大小写 0-区分大小写
修改/etc/my.cnf 具体的修改内容如下:
[client]
default-character-set=utf8
[mysqld]
datadir=/var/lib/mysql
socket=/va
我的spring学习笔记6-ApplicationContext实例化的参数兼容思想
aijuans
Spring 3
ApplicationContext能读取多个Bean定义文件,方法是:
ApplicationContext appContext = new ClassPathXmlApplicationContext(
new String[]{“bean-config1.xml”,“bean-config2.xml”,“bean-config3.xml”,“bean-config4.xml
mysql 基准测试之sysbench
annan211
基准测试 mysql基准测试 MySQL测试 sysbench
1 执行如下命令,安装sysbench-0.5:
tar xzvf sysbench-0.5.tar.gz
cd sysbench-0.5
chmod +x autogen.sh
./autogen.sh
./configure --with-mysql --with-mysql-includes=/usr/local/mysql
sql的复杂查询使用案列与技巧
百合不是茶
oracle sql 函数 数据分页 合并查询
本片博客使用的数据库表是oracle中的scott用户表;
------------------- 自然连接查询
查询 smith 的上司(两种方法)
&
深入学习Thread类
bijian1013
java thread 多线程 java多线程
一. 线程的名字
下面来看一下Thread类的name属性,它的类型是String。它其实就是线程的名字。在Thread类中,有String getName()和void setName(String)两个方法用来设置和获取这个属性的值。
同时,Thr
JSON串转换成Map以及如何转换到对应的数据类型
bijian1013
java fastjson net.sf.json
在实际开发中,难免会碰到JSON串转换成Map的情况,下面来看看这方面的实例。另外,由于fastjson只支持JDK1.5及以上版本,因此在JDK1.4的项目中可以采用net.sf.json来处理。
一.fastjson实例
JsonUtil.java
package com.study;
impor
【RPC框架HttpInvoker一】HttpInvoker:Spring自带RPC框架
bit1129
spring
HttpInvoker是Spring原生的RPC调用框架,HttpInvoker同Burlap和Hessian一样,提供了一致的服务Exporter以及客户端的服务代理工厂Bean,这篇文章主要是复制粘贴了Hessian与Spring集成一文,【RPC框架Hessian四】Hessian与Spring集成
在
【RPC框架Hessian二】Hessian 对象序列化和反序列化一文中
【Mahout二】基于Mahout CBayes算法的20newsgroup的脚本分析
bit1129
Mahout
#!/bin/bash
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information re
nginx三种获取用户真实ip的方法
ronin47
随着nginx的迅速崛起,越来越多公司将apache更换成nginx. 同时也越来越多人使用nginx作为负载均衡, 并且代理前面可能还加上了CDN加速,但是随之也遇到一个问题:nginx如何获取用户的真实IP地址,如果后端是apache,请跳转到<apache获取用户真实IP地址>,如果是后端真实服务器是nginx,那么继续往下看。
实例环境: 用户IP 120.22.11.11
java-判断二叉树是不是平衡
bylijinnan
java
参考了
http://zhedahht.blog.163.com/blog/static/25411174201142733927831/
但是用java来实现有一个问题。
由于Java无法像C那样“传递参数的地址,函数返回时能得到参数的值”,唯有新建一个辅助类:AuxClass
import ljn.help.*;
public class BalancedBTree {
BeanUtils.copyProperties VS PropertyUtils.copyProperties
诸葛不亮
PropertyUtils BeanUtils
BeanUtils.copyProperties VS PropertyUtils.copyProperties
作为两个bean属性copy的工具类,他们被广泛使用,同时也很容易误用,给人造成困然;比如:昨天发现同事在使用BeanUtils.copyProperties copy有integer类型属性的bean时,没有考虑到会将null转换为0,而后面的业
[金融与信息安全]最简单的数据结构最安全
comsci
数据结构
现在最流行的数据库的数据存储文件都具有复杂的文件头格式,用操作系统的记事本软件是无法正常浏览的,这样的情况会有什么问题呢?
从信息安全的角度来看,如果我们数据库系统仅仅把这种格式的数据文件做异地备份,如果相同版本的所有数据库管理系统都同时被攻击,那么
vi区段删除
Cwind
linux vi 区段删除
区段删除是编辑和分析一些冗长的配置文件或日志文件时比较常用的操作。简记下vi区段删除要点备忘。
vi概述
引文中并未将末行模式单独列为一种模式。单不单列并不重要,能区分命令模式与末行模式即可。
vi区段删除步骤:
1. 在末行模式下使用:set nu显示行号
非必须,随光标移动vi右下角也会显示行号,能够正确找到并记录删除开始行
清除tomcat缓存的方法总结
dashuaifu
tomcat 缓存
用tomcat容器,大家可能会发现这样的问题,修改jsp文件后,但用IE打开 依然是以前的Jsp的页面。
出现这种现象的原因主要是tomcat缓存的原因。
解决办法如下:
在jsp文件头加上
<meta http-equiv="Expires" content="0"> <meta http-equiv="kiben&qu
不要盲目的在项目中使用LESS CSS
dcj3sjt126com
Web less
如果你还不知道LESS CSS是什么东西,可以看一下这篇文章,是我一朋友写给新人看的《CSS——LESS》
不可否认,LESS CSS是个强大的工具,它弥补了css没有变量、无法运算等一些“先天缺陷”,但它似乎给我一种错觉,就是为了功能而实现功能。
比如它的引用功能
?
.rounded_corners{
[入门]更上一层楼
dcj3sjt126com
PHP yii2
更上一层楼
通篇阅读完整个“入门”部分,你就完成了一个完整 Yii 应用的创建。在此过程中你学到了如何实现一些常用功能,例如通过 HTML 表单从用户那获取数据,从数据库中获取数据并以分页形式显示。你还学到了如何通过 Gii 去自动生成代码。使用 Gii 生成代码把 Web 开发中多数繁杂的过程转化为仅仅填写几个表单就行。
本章将介绍一些有助于更好使用 Yii 的资源:
Apache HttpClient使用详解
eksliang
httpclient http协议
Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们再讨论),它不仅是客户端发送Http请求变得容易,而且也方便了开发人员测试接口(基于Http协议的),即提高了开发的效率,也方便提高代码的健壮性。因此熟练掌握HttpClient是很重要的必修内容,掌握HttpClient后,相信对于Http协议的了解会
zxing二维码扫描功能
gundumw100
android zxing
经常要用到二维码扫描功能
现给出示例代码
import com.google.zxing.WriterException;
import com.zxing.activity.CaptureActivity;
import com.zxing.encoding.EncodingHandler;
import android.app.Activity;
import an
纯HTML+CSS带说明的黄色导航菜单
ini
html Web html5 css hovertree
HoverTree带说明的CSS菜单:纯HTML+CSS结构链接带说明的黄色导航
在线体验效果:http://hovertree.com/texiao/css/1.htm代码如下,保存到HTML文件可以看到效果:
<!DOCTYPE html >
<html >
<head>
<title>HoverTree
fastjson初始化对性能的影响
kane_xie
fastjson 序列化
之前在项目中序列化是用thrift,性能一般,而且需要用编译器生成新的类,在序列化和反序列化的时候感觉很繁琐,因此想转到json阵营。对比了jackson,gson等框架之后,决定用fastjson,为什么呢,因为看名字感觉很快。。。
网上的说法:
fastjson 是一个性能很好的 Java 语言实现的 JSON 解析器和生成器,来自阿里巴巴的工程师开发。
基于Mybatis封装的增删改查实现通用自动化sql
mengqingyu
DAO
1.基于map或javaBean的增删改查可实现不写dao接口和实现类以及xml,有效的提高开发速度。
2.支持自定义注解包括主键生成、列重复验证、列名、表名等
3.支持批量插入、批量更新、批量删除
<bean id="dynamicSqlSessionTemplate" class="com.mqy.mybatis.support.Dynamic
js控制input输入框的方法封装(数字,中文,字母,浮点数等)
qifeifei
javascript js
在项目开发的时候,经常有一些输入框,控制输入的格式,而不是等输入好了再去检查格式,格式错了就报错,体验不好。 /** 数字,中文,字母,浮点数(+/-/.) 类型输入限制,只要在input标签上加上 jInput="number,chinese,alphabet,floating" 备注:floating属性只能单独用*/
funct
java 计时器应用
tangqi609567707
java timer
mport java.util.TimerTask; import java.util.Calendar; public class MyTask extends TimerTask { private static final int
erlang输出调用栈信息
wudixiaotie
erlang
在erlang otp的开发中,如果调用第三方的应用,会有有些错误会不打印栈信息,因为有可能第三方应用会catch然后输出自己的错误信息,所以对排查bug有很大的阻碍,这样就要求我们自己打印调用的栈信息。用这个函数:erlang:process_display (self (), backtrace).需要注意这个函数只会输出到标准错误输出。
也可以用这个函数:erlang:get_s