freemarker自定义标签
程序员文章站
2022-06-08 23:47:02
...
今天项目中要用到自定义标签,发现下面的问题
1 .freemarker里面获取HttpServletRequest没有办法获取,最后还是通过spring的一个listener解决的
在web.xml里面添加下面的配置:
<listener> <listener-class> org.springframework.web.context.request.RequestContextListener </listener-class> </listener>
java代码通过下面方式获取request:
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
HttpServletRequest request = attr.getRequest();
2. 标签必须有空格,否则body为空,如下:
页面中的写法:
<@head> </@head>
中间必须有一个空格,否则body就为空
@Override
public void execute(Environment env, Map params, TemplateModel[] loopVars,
TemplateDirectiveBody body) throws TemplateException, IOException {
Writer out = env.getOut();
String locale = this.getParam(params, "locale");
if(StringUtils.isBlank(locale)){
locale = resolveLocale();
}
String template = TemplateFactory.generateHtmlFromFtl(getTempateName(), locale, specificMap(params));
out.write(template);
if (body != null) {
body.render(env.getOut());
} else {
throw new RuntimeException("标签内部至少要加一个空格");
}
}
3. 在freemarker的标签里面无法定义像jsptag那样那些参数是必填项,那些是非必填项,也就意味着所有的参数都必须做好default处理,比如下面的:
Writer out = env.getOut();
String locale = this.getParam(params, "locale");
if(StringUtils.isBlank(locale)){
locale = resolveLocale();
}
无法定义locale是必须得,这样在页面渲染的时候像jsptag那样就报错。
最后分享下我的TemplateFactory,可以直接用奥。
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class TemplateFactory {
// 日志记录对象
private final static Logger log = LoggerFactory.getLogger(TemplateFactory.class);
// 模板文件路径
private final static String templatePath = "/config/template";
// 模板文件内容编码
private final static String ENCODING = "utf-8";
private final static String SUFFIX = ".ftl";
// 模板生成配置
private static Configuration conf = new Configuration();
// 邮件模板缓存池
private static Map<String, Template> tempMap = new HashMap<String, Template>();
static {
// 设置模板文件路径
conf.setClassForTemplateLoading(TemplateFactory.class, templatePath);
conf.setDefaultEncoding(ENCODING);
}
/**
* 通过模板文件名称获取指定模板
*
* @Date:2014年4月26日 下午3:09:05
* @author
* @param name
* 模板文件名称
* @return Template 模板对象
* @throws IOException
* @Description:
* @return Template
*/
private static Template getTemplateByName(String name,String locale) throws IOException {
name = name + "_" + locale + SUFFIX;
if (tempMap.containsKey(name)) {
log.debug("the template is already exist in the map,template name :"
+ name);
// 缓存中有该模板直接返回
return tempMap.get(name);
}
// 缓存中没有该模板时,生成新模板并放入缓存中
Template temp = conf.getTemplate(name);
tempMap.put(name, temp);
log.debug("the template is not found in the map,template name :"
+ name);
return temp;
}
/**
* 根据指定模板将内容输出到控制台
*
* @Date:2014年4月26日 下午3:14:18
* @author
* @param name
* 模板文件名称
* @param map
* 与模板内容转换对象
* @Description:
* @return void
*/
public static void outputToConsole(String name,String locale,Map<String, String> map) {
try {
// 通过Template可以将模板文件输出到相应的流
Template temp = getTemplateByName(name,locale);
temp.setEncoding(ENCODING);
temp.process(map, new PrintWriter(System.out));
} catch (TemplateException e) {
log.error(e.toString(), e);
} catch (IOException e) {
log.error(e.toString(), e);
}
}
/**
*
* @Date:2014年4月26日 下午3:24:37
* @author
* @param name
* 模板文件的名称
* @param map
* 与模板内容转换对象
* @return
* @throws IOException
* @throws TemplateException
* @Description:
* @return String
*/
public static String generateHtmlFromFtl(String name,String locale,
Map<String, String> map) throws IOException, TemplateException {
Writer out = new StringWriter(2048);
Template temp = getTemplateByName(name,locale);
temp.setEncoding(ENCODING);
temp.process(map, out);
return out.toString();
}
}