freemaker

本文介绍如何使用Freemarker模板引擎生成Java Bean类文件,包括自定义宏实现首字母大写功能,以及通过示例演示整个过程。

项目准备:先去down个freemarker.jar包,  http://freemarker.org/freemarkerdownload.html

上篇讨论了代码生成器的原理,输出=模板+数据,那么现在就生成一个Student.java文件做个简单例子。

首先先写出模板,先解决一个问题,上篇有讲到属性名首字母大写的问题

由于freemarker中不支持将首字母大写(属性名中用到),那么自己先写一个自定义宏如下:

package com;

import java.io.IOException;
import java.io.Writer;
import java.util.Map;

import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;

public class UpperFirstCharacter implements TemplateDirectiveModel {

    public void execute(Environment env,
            Map params, TemplateModel[] loopVars,
            TemplateDirectiveBody body)
            throws TemplateException, IOException {
        // Check if no parameters were given:
        if (!params.isEmpty()) {
            throw new TemplateModelException(
                    "This directive doesn't allow parameters.");
        }
        if (loopVars.length != 0) {
                throw new TemplateModelException(
                    "This directive doesn't allow loop variables.");
        }
        
        // If there is non-empty nested content:
        if (body != null) {
            // Executes the nested body. Same as <#nested> in FTL, except
            // that we use our own writer instead of the current output writer.
            body.render(new UpperCaseFilterWriter(env.getOut()));
        } else {
            throw new RuntimeException("missing body");
        }
    }
    
    /**
     * A {@link Writer} that transforms the character stream to upper case
     * and forwards it to another {@link Writer}.
     */ 
    private static class UpperCaseFilterWriter extends Writer {
       
        private final Writer out;
           
        UpperCaseFilterWriter (Writer out) {
            this.out = out;
        }

        public void write(char[] cbuf, int off, int len)
                throws IOException {
//            char[] transformedCbuf = new char[len];
//            for (int i = 0; i < len; i++) {
//                transformedCbuf[i] = Character.toUpperCase(cbuf[i + off]);
//            }
//            out.write(transformedCbuf);
        	cbuf[0] = Character.toUpperCase(cbuf[0]);
        	out.write(String.valueOf(cbuf).trim());///把右边空格去掉
        }

        public void flush() throws IOException {
            out.flush();
        }

        public void close() throws IOException {
            out.close();
        }
    }

}

 

下面呢就可以编写模板了,代码如下:

package ${package};

//这个地方可以事先定义好需要的类
import java.util.Date;

import java.io.Serializable;

public class ${className} implements Serializable{
<#list properties as pro>
	private ${pro.proType} ${pro.proName};
</#list>
	
<#list properties as pro>
	public void set<@upperFC>${pro.proName}</@upperFC>(${pro.proType} ${pro.proName}){
		this.${pro.proName}=${pro.proName};
	}
	
	public ${pro.proType} get<@upperFC>${pro.proName}</@upperFC>(){
		return this.${pro.proName};
	}
	
</#list>
}

模板文件取名为javabean.html,在com包下

下面编写测试类:

package com;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//System.out.println(System.getProperty("user.dir")+"============");
		Configuration cfg = new Configuration();
		try {
        	cfg.setClassForTemplateLoading(Test.class, "/com");//指定模板所在的classpath目录
        	cfg.setSharedVariable("upperFC", new UpperFirstCharacter());//添加一个"宏"共享变量用来将属性名首字母大写
			Template t = cfg.getTemplate("javabean.html");//指定模板
			FileOutputStream fos = new FileOutputStream(new File("d:/Student.java"));//java文件的生成目录
			
			//模拟数据源
			Map data = new HashMap();
			data.put("package", "edu");//包名
			data.put("className", "Student");
			
			List pros = new ArrayList();
			Map pro_1 = new HashMap();
			pro_1.put("proType", String.class.getSimpleName());
			pro_1.put("proName", "name");
			pros.add(pro_1);
			
			Map pro_2 = new HashMap();
			pro_2.put("proType", String.class.getSimpleName());
			pro_2.put("proName", "sex");
			pros.add(pro_2);
			
			Map pro_3 = new HashMap();
			pro_3.put("proType", Integer.class.getSimpleName());
			pro_3.put("proName", "age");
			pros.add(pro_3);
			
			data.put("properties", pros);
			t.process(data, new OutputStreamWriter(fos,"utf-8"));//
			fos.flush();
			fos.close();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (TemplateException e) {
			e.printStackTrace();
		}
	}

}

 

运行一下测试类,在D盘可以找到一个Student.java的文件,打开看看对不对

 

 

 

 

 

 

package freemarker;
  
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.Template;
  
public class Test1 {
 private Configuration cfg;
  
 public Configuration getCfg() {
  return cfg;
 }
  
 public void init() throws Exception {
  cfg = new Configuration();
  cfg.setDirectoryForTemplateLoading(new File("bin/freemaker"));
 }
  
 public static void main(String[] args) throws Exception {
  Test1 obj = new Test1();
  obj.init();
  Map root = new HashMap();
  Template t = obj.getCfg().getTemplate("Test.ftl");
  Writer out = new OutputStreamWriter(new FileOutputStream("Test.html"), "GBK");
  t.process(root, out);
  System.out.println("Successfull................");
 }
}

  4 使用到的'静态'模板 Test.ftl

<#macro greet person,website>
 Hello ${person}! Your Website is ${website}.
</#macro>
<html>
<head>
 <title>Hello World</title>
</head>
<body>
<@greet person="fff" website="www.ffff.com"/>
</body>
</html>

  5 运行结果

<html>
<head>
 <title>Hello World</title>
</head>
<body>
 HelloYour Website is <a target="_blank" href="www.ffff.com">www.ffff.com</a>
</body>
</html>

 

======================================================================

 

 

步骤:
1、在工程中引入freemark的jar包。
2、写一个freemark页面模板,如:freemarkForWebTemplate.ftl,该文件以ftl为后缀。我就以一个最简单的为例子:
freemarkForWebTemplate.ftl内容为:
hello ,${name}
3、在struts的action里写转载的逻辑:
//得到配置对象
Configuration configuration = new Configuration();
//设置生成模板加载方式(由servletcontext生成)
configuration.setServletContextForTemplateLoading(this.getServletContext(), "WEB-INF/template(你模板的位置)");
//生成数据模型
Map root = new HashMap();
root.put("name(你模板中的变量以上面模板为例)", "world");
//得到模板
Template template = configuration.getTemplate("freemarkForWebTemplate.ftl(你的模板名)");
try {
//输出模板
template.process(root, resp.getWriter());
} catch (TemplateException e) {
e.printStackTrace();
}
这样你就行了,否用的struts1,如果是strus2的话更简单。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值