freemarker自定义标签(与java合用)

Posted 星朝

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了freemarker自定义标签(与java合用)相关的知识,希望对你有一定的参考价值。

自定义类继承FreemarkerManager类,重写protected Configuration createConfiguration(ServletContext servletContext)throws TemplateException方法定义有哪些TemplateDirectiveModel类与它的别名[自定义标签名称],通过Spring来取:

技术分享图片
import java.util.Map;
import javax.servlet.ServletContext;
import org.apache.struts2.views.freemarker.FreemarkerManager;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import freemarker.template.Configuration;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
/**
* 从spring取得所有的TemplateDirectiveModel类的对象,全部取出来,交给struts管理
*
@author Administrator

*
*/
public class DirectiveFreemarkerManager extends FreemarkerManager{
@Override
protected Configuration createConfiguration(ServletContext servletContext)
throws TemplateException {
//调用你父类操作
Configuration configuration=super.createConfiguration(servletContext);
//设定在页面使用的标签的类型 (([]、<>),[]这种标记解析要快些) [] SQUARE_BRACKET_TAG_SYNTAX , <>ANGLE_BRACKET_TAG_SYNTAX
configuration.setTagSyntax(Configuration.AUTO_DETECT_TAG_SYNTAX);
//取得spring所管理所有的对象 ClassPathXmlApplication, WebAplicationContext
ApplicationContext appContext=WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
// 获取实现TemplateDirectiveModel的bean
Map<String, TemplateDirectiveModel> beans= appContext.getBeansOfType(TemplateDirectiveModel.class);
//再把这些类,全部交给struts的freemarker来管理
//Component("upper") public class UpperDirective implements TemplateDirectiveModel
for(String key : beans.keySet()){
Object obj
=beans.get(key); //TemplateDirectiveModel
if(obj!=null && obj instanceof TemplateDirectiveModel){
configuration.setSharedVariable(key, obj);
}
}
return configuration;
}}
技术分享图片

在struts.xml中添加:

 <!-- 让struts来管理freemarker自定义标签类 struts.freemarker.manager.classname=org.apache.struts2.views.freemarker.FreemarkerManager -->    <constant name="struts.freemarker.manager.classname" value="com.xxxx.struts.DirectiveFreemarkerManager"></constant>

编写TemplateDirectiveModel,并交给Spring管理:

技术分享图片
import java.io.IOException;
import java.io.Writer;
import java.util.Map;
import org.springframework.stereotype.Component;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;

/**
* 自定义指定,作用,把嵌套的内容中的小写全部转换为大写字母
*
*
@author Administrator

*
*/
@Component(
"upper")
public class UpperDirective implements TemplateDirectiveModel {
//evn 环境输出
//params 参数
//loopVars 循环
//body 内容
@Override
public void execute(Environment env, Map params,
TemplateModel[] loopVars, TemplateDirectiveBody body)
throws TemplateException, IOException {
//如果有参数 应该不支持参数
if(!params.isEmpty()){
throw new TemplateModelException(
"这个指令不允许使用参数.");
}
if(loopVars.length!=0){
throw new TemplateModelException(
"这个指令不允许使用循环参数.");
}
// 如果嵌套内容不为空的
if(body!=null){
//如果有内容,自己去重写输出流
body.render( new UpperCaseFilterWriter(env.getOut()));

}
else{
throw new RuntimeException("无内容异常");
}
}
//内部类
private static class UpperCaseFilterWriter extends Writer{
private final Writer out; //接收网页中的输出 流对象
public UpperCaseFilterWriter(Writer out){
this.out=out;
}
//cbuf 文字内容, off位移,len 文字长度
@Override
public void write(char[] cbuf, int off, int len) throws IOException {
char[] transformedChar=new char[len];
for(int i=0;i<len;i++){
transformedChar[i]
=Character.toUpperCase(cbuf[i+off]);
}
out.write(transformedChar);
}
@Override
public void flush() throws IOException {
out.flush();
}
@Override
public void close() throws IOException {
out.close();
}
}
}
技术分享图片

编写action,result—>字符串,type=”freemarker”:

<!-- 约定大于配置   /admin/Flinktype_list.action  --> 
<package name="freemarkerPackage" namespace="/admin" extends="commonPackage" >
<action name="*_*" class="{1}Action" method="{2}">
<result name="{2}" type="freemarker">/admin/template/{1}/{2}.ftl</result>
</action>
</package>

模板/template/upper.ftl:

技术分享图片
<!DOCTYPE html>
<html lang="ch-ZN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>freemarker自定义标签</title></head>
<body>

<@upper>
bar
<#-- All kind of FTL is allowed here -->
<#list ["red", "green", "blue"] as color>
${color}
</#list>
baaz
</@upper>


<hr/>

<@cms_linktype limit="0,10" >
请选择分类:
<select>
<#list arrTypes as x>
<option value="${x.id}">${x.typeName}</option>
</#list>
</select>
</@cms_linktype>
</body>
技术分享图片

 










































































































































以上是关于freemarker自定义标签(与java合用)的主要内容,如果未能解决你的问题,请参考以下文章

SpringMVC和Freemarker整合,带自定义标签的使用方法

SpringBoot整合freemarker中自定义标签获取字典表的数据

请问下freemarker怎么引入了jstl标签啊?

在js中使用freemarker的标签比如 include 等

怎么在html中写自定义freemaker标签

freemarker自己定义标签报错