020_程序方法

1. 方法变量在存于实现了TemplateMethodModel接口的模板中。这个接口包含一个方法: TemplateModel exec(java.util.List arguments)。

2. 当使用FTL方法调用表达式时, exec方法将会被调用。形参将会包含FTL方法调用形参的值。exec方法的返回值给出了FTL方法调用表达式的返回值。

3. TemplateMethodModelEx接口扩展了TemplateMethodModel接口。它没有添加任何新方法。事实上这个对象实现这个标记接口是给FTL引擎暗示, 形式参数应该直接以TemplateModel的形式放进java.util.List。否则将会以String形式放入list。

020_程序方法

4. 例子

4.1. 新建一个名为FMProgrammingMethod的动态Web工程, 同时添加相关jar包。

020_程序方法

4.2. 编写FMFactory.java

package com.fm.util;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import freemarker.template.Configuration;
import freemarker.template.TemplateExceptionHandler;

public class FMFactory {
	private final static FMFactory instance = new FMFactory();
	private FMFactory() {}
	public static FMFactory getInstance() {
		return instance;
	}
	
	private Map<String, Configuration> map = new ConcurrentHashMap<String, Configuration>();
	
	// 创建单个Configuration实例
	public synchronized Configuration getCfg(Object servletContext, String path) {
		if(null != map.get(path)) {
			return map.get(path);
		}
	
		Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);
		cfg.setServletContextForTemplateLoading(servletContext, path);
		cfg.setDefaultEncoding("utf-8");
		cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
		map.put(path, cfg);
		
		return cfg;
	}
	
}

4.3. 编写IndexOfMethod.java

package com.fm.action;

import java.util.List;
import freemarker.template.SimpleNumber;
import freemarker.template.SimpleScalar;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;

/**
 * 返回第一个字符串在第二个字符串第一次出现时的索引位置, 如果第二个字符串中不包含第一个字符串, 则返回-1。
 */
public class IndexOfMethod implements TemplateMethodModelEx {

	public TemplateModel exec(List args) throws TemplateModelException {
		if (args.size() != 2) {
			throw new TemplateModelException("Wrong arguments");
		}
		return new SimpleNumber(((SimpleScalar) args.get(1)).getAsString().indexOf(((SimpleScalar) args.get(0)).getAsString()));
	}
}

4.4. 编写ProgrammingMethod.java

package com.fm.action;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.fm.util.FMFactory;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

public class ProgrammingMethod extends HttpServlet {
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		Configuration cfg = FMFactory.getInstance().getCfg(req.getServletContext(), "/WEB-INF/templates");
		Template template = cfg.getTemplate("programmingmethod.html");
		
		Map<String, Object> root = new HashMap<String, Object>();
		root.put("indexOf", new IndexOfMethod());
		
		Writer out = new OutputStreamWriter(resp.getOutputStream());
		try {
			template.process(root, out);
		} catch (TemplateException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doGet(req, resp);
	}
}

4.5. 修改web.xml

020_程序方法

4.6. 在/WEB-INF/templates目录下编写programmingmethod.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>程序方法</title>
	</head>
	<body>
		<h2>返回第一个字符串在第二个字符串第一次出现时的索引位置</h2>
		"met"在"something"第${indexOf("met", "something")}个位置<br />

		<#assign idx = indexOf("foo", "something") />
		<#if idx == -1>
			"foo"在"something"中没有找到。
		<#else>
			"foo"在"something"第${idx}个位置
		</#if>
	</body>
</html>

4.7. 运行项目

020_程序方法

 

上一篇:freemarker:jar:2.3.23 maven下载不了


下一篇:freemarker中js里面取字符串,换行导致报错的解决办法