文档章节

关于java代码生成器---下篇之实例

William
 William
发布于 2010/05/19 20:15
字数 645
阅读 4239
收藏 10

项目准备:先去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的文件,打开看看对不对

© 著作权归作者所有

William
粉丝 8
博文 26
码字总数 7874
作品 0
浦东
程序员
私信 提问
加载中

评论(1)

k
kachusya
我运行了出错:
2012-10-10 9:15:26 freemarker.log.JDK14LoggerFactory$JDK14Logger error
严重:

on line 14, column 24 in javabean.html: upperFC is not a Macro or Transform.
The problematic instruction:
----------
==> user-directive upperFC [on line 14, column 24 in javabean.html]
----------

Java backtrace for programmers:
----------
freemarker.template.TemplateException: on line 14, column 24 in javabean.html: upperFC is not a Macro or Transform.
  at freemarker.core.UnifiedCall.accept(UnifiedCall.java:140)
  at freemarker.core.Environment.visit(Environment.java:196)
  at freemarker.core.MixedContent.accept(MixedContent.java:92)
  at freemarker.core.Environment.visit(Environment.java:196)
  at freemarker.core.IteratorBlock$Context.runLoop(IteratorBlock.java:172)
  at freemarker.core.Environment.visit(Environment.java:351)
  at freemarker.core.IteratorBlock.accept(IteratorBlock.java:95)
  at freemarker.core.Environment.visit(Environment.java:196)
  at freemarker.core.MixedContent.accept(MixedContent.java:92)
  at freemarker.core.Environment.visit(Environment.java:196)
  at freemarker.core.Environment.process(Environment.java:176)
  at freemarker.template.Template.process(Template.java:232)
  at com.Test.main(Test.java:51)

on line 14, column 24 in javabean.html: upperFC is not a Macro or Transform.
The problematic instruction:
----------
==> user-directive upperFC [on line 14, column 24 in javabean.html]
----------

Java backtrace for programmers:
----------
freemarker.template.TemplateException: on line 14, column 24 in javabean.html: upperFC is not a Macro or Transform.
  at freemarker.core.UnifiedCall.accept(UnifiedCall.java:140)
  at freemarker.core.Environment.visit(Environment.java:196)
  at freemarker.core.MixedContent.accept(MixedContent.java:92)
  at freemarker.core.Environment.visit(Environment.java:196)
  at freemarker.core.IteratorBlock$Context.runLoop(IteratorBlock.java:172)
  at freemarker.core.Environment.visit(Environment.java:351)
  at freemarker.core.IteratorBlock.accept(IteratorBlock.java:95)
  at freemarker.core.Environment.visit(Environment.java:196)
  at freemarker.core.MixedContent.accept(MixedContent.java:92)
  at freemarker.core.Environment.visit(Environment.java:196)
  at freemarker.core.Environment.process(Environment.java:176)
  at freemarker.template.Template.process(Template.java:232)
  at com.Test.main(Test.java:51)
可视化界面代码生成器 - auto-code-ui-spring-boot-starter

auto-code-ui-spring-boot-starter 欢迎使用auto-code-ui-spring-boot-starter可视化界面代码生成器. 演示地址 介绍 传统的java web配置过于繁琐.spring boot的核心思想就是基于约定的配置....

zengtengpe
03/22
4.4K
2
老树新花,和平之翼代码生成器S2SM版发布新版0.9版本

和平之翼代码生成器S2SM工作组版 本版是和平之翼Java代码生成器S2SM 0.9.0版。 S2SM技术栈支持Struts 2,spring4,MyBatis 3。 和平之翼Java代码生成器是动词算子式Java通用代码生成器,是无垠...

火箭船
2018/11/09
441
0
无垠式Java通用代码生成器经典版本最新更新版

无垠式Java通用代码生成器经典版本最新更新版0.8.5发布了。 此版本基于经典的无垠式代码生成器三引擎版0.8.0。包含simplejee,s2sh和s2shc三种技术栈x。本更新版生成引擎并未更新。只是升级S...

火箭船
2018/10/27
7
0
老树新花,和平之翼代码生成器SHC发布新版0.9版本

本版是和平之翼Java代码生成器SHC 0.9版。在0.8版的基础上增强了语法加亮的SGS代码编辑器。并有文档更新和全面测试。欢迎使用。 SHC技术栈支持Spring MVC4,spring4,Hibernate 4 Criteria。 ...

火箭船
2018/11/05
1
0
老树新花,和平之翼代码生成器 SHC 发布 0.9 版本

本版是和平之翼Java代码生成器SHC 0.9版。在0.8版的基础上增强了语法加亮的SGS代码编辑器。并有文档更新和全面测试。欢迎使用。 SHC技术栈支持Spring MVC4,spring4,Hibernate 4 Criteria。 ...

火箭船
2018/11/05
464
1

没有更多内容

加载失败,请刷新页面

加载更多

SSH安全加强两步走

从 OpenSSH 6.2 开始已经支持 SSH 多因素认证,本文就来讲讲如何在 OpenSSH 下启用该特性。 OpenSSH 6.2 以后的版本多了一个配置项 AuthenticationMethods。该配置项可以让 OpenSSH 同时指定...

xiangyunyan
23分钟前
2
0
C或C++不是C/C++

http://www.voidcn.com/article/p-mucdruqa-ws.html

shzwork
今天
6
0
OSChina 周六乱弹 —— 如何将梳子卖给和尚

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @for_ :划水五分钟,专注两小时。分享Various Artists的单曲《贝多芬第8号钢琴奏鸣曲悲伤的第三乐章》: 《贝多芬第8号钢琴奏鸣曲悲伤的第三乐...

小小编辑
今天
175
8
ES5

什么是ES5:比普通js运行要求更加严格的模式 为什么:js语言本身有很多广受诟病的缺陷 如何:在当前作用域的顶部添加:"use strict" 要求: 1、禁止给未声明的变量赋值 2、静默失败升级为错误...

wytao1995
今天
7
0
c++ 内联函数调用快的原因

见图片分析

天王盖地虎626
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部