最近刚刚转正没多久,正好前天部门大佬让我和一个同事做一个自动化的软件测试程序,通过导入一些excel的测试数据表格来生成测试html报告。而我负责的主要是freemarker生成html还有另外一个同事通过jar包调用我的方法.前者的freemarker转静态页面还是比较简单的,后者的话刚刚听到这个需求的时候其实我觉得有点迷惑,为什么不直接做成一个web应用或者打成一个jar包 还要打成几个jar包?后来我自己想了一下应该是考虑到这个测试应用是给一些不太懂代码的测试人员使用,还有就是打成几个jar包的话应该是为了解耦,对外提供接口,这样以后有其他web应用也可以调用这个jar包。
之前一直做web应用比较多,打war包比较多,对于jar包了解的还是比较少。不过对于调用jar包里的方法,我脑海里浮出的第一个想法是——java反射。后来在大佬的提示和自己的查找资料也证实了这个想法。
首先,介绍一下两个项目的目录结构,两个项目都是普通java project
到这里可能有人会问 为什么不用maven 为什么不用spring
不用maven是因为maven相当于依赖的路径导入 并没有导入真正的jar包支持
所以当你项目打成jar包就会报错找不到class
而不用spring是为了减少导入spring的 jar包 为了介绍体积
看图二可以知道我只导入了一个freemarker的jar包
dynamic-invoke-test中的invoke类将会调用 打成jar包后的freemarkerutil-test.jar的方法
首先我们定义dto
package com.way.dto;
public class Student {
private String name;
private String age;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Student(String name, String age, String sex) {
super();
this.name = name;
this.age = age;
this.sex = sex;
}
public Student() {
super();
}
}
还有freemarker的ftl模板 freemarker比较简单容易上手 大家就自行去搜索资料吧
<html>
<head>
<meta charset="UTF-8">
<title>学生信息</title>
</head>
<body>
<center><h1>学生信息管理</h1></center>
<table border="1" cellspacing="0" align="center">
<tr>
<td>姓名:</td>
<td>${student.name}</td>
</tr>
<tr>
<td>年龄:</td>
<td>${student.age}</td>
</tr>
<tr>
<td>性别:</td>
<td>${student.sex}</td>
</tr>
</table>
</body>
</html>
ftl模板存放的路径我下面有提到
FreemarkerUtil.java
package com.way.util;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.way.dto.Student;
import freemarker.core.ParseException;
import freemarker.template.Configuration;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateNotFoundException;
/**
*
* @author Way Liang ASNPHXW
*
* @date Jul 3, 2018
*
* @description:
*
*/
public class FreemarkerUtil {
public static void main(String[] args) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException{
// 添加数据
Student student = new Student("way", "23", "male");
generateStudentHtml(student);
}
public static void generateStudentHtml(Student student) throws IOException, TemplateException{
//获取ftl模板
Template template = getTemplateByFtlName("student.ftl");
//String outPutPath = "src"+File.separator+"main"+File.separator+"webapp"+File.separator+"WEB-INF"+File.separator+"html"+File.separator+"summary.html";
String outPutPath = File.separator+"html"+File.separator+"student.html";
String substring = outPutPath .substring(0, outPutPath.lastIndexOf(File.separator));
//System.out.println(substring);
File f = new File(substring);
Map<String, Object> datamap = new HashMap<String, Object>();
datamap.put("student", student);
//System.out.println("---generateSummaryHtml "+outPutPath);
if(!f.exists()){
f.mkdirs();
}
// 输出文件路径
Writer wr = new FileWriter(outPutPath);
// 写入
template.process(datamap, wr);
// 关闭流
wr.close();
}
/**
* 根据模板名获取ftl模板
* @param ftlName
* @return
* @throws TemplateNotFoundException
* @throws MalformedTemplateNameException
* @throws ParseException
* @throws IOException
*/
public static Template getTemplateByFtlName(String ftlName) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException{
// 第一步:创建一个Configuration对象,直接new一个对象。构造方法的参数就是freemarker对于的版本号。
Configuration configuration = new Configuration(Configuration.getVersion());
// 第二步:设置模板文件所在的路径。
configuration.setDirectoryForTemplateLoading(new File(File.separator+"freemarker/"));
// 第三步:设置模板文件使用的字符集。一般就是utf-8.
configuration.setDefaultEncoding("utf-8");
// 获取ftl,由于已经在配置文件中配置了路径所以在这里直接写模板名称就可以
Template template = configuration.getTemplate(ftlName);
return template;
}
}
这里要注意的是(new File(File.separator+"freemarker/"));的路径是你项目所在的盘的绝对路径
例如我的项目在D盘所以我的放freemarker ftl模板的路径是D:\freemarker
还有
String outPutPath = File.separator+"html"+File.separator+"student.html";
生成的html模板也是项目所在盘的绝对路径 例如我的就是生成在 D:\html
然后还有Invoke.java
package com.way.test;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import com.way.dto.Student;
/**
*
* @author Way Liang asnphxw
*
* @date Jul 4, 2018
*
* @description:
*
*/
public class Invoke {
private static int flag = 0;
private static String softPath;
@SuppressWarnings({ "unchecked", "resource", "rawtypes" })
public static void main(String[] args) throws Exception {
//调用的jar包位置
String softPath = "file:D:"+File.separator+"jar"+File.separator+"freemarkerutil-test.jar";
URLClassLoader classLoader = new URLClassLoader(new URL[]{new URL(softPath)},Thread.currentThread().getContextClassLoader());
Class demo = classLoader.loadClass("com.way.util.FreemarkerUtil");
Object object = demo.newInstance();
Student student = new Student("way", "23", "male");
demo.getMethod("generateStudentHtml",Student.class).invoke(object, student);
}
}
要注意的是softPath是我用eclipse导出jar包后的位置
然后还有 classLoader.loadClass("com.way.util.FreemarkerUtil") 包名都要对应
最后是把freemarkerutil-test打成jar包
我用的是eclipse 右键freemarkerutil-test 点export
注意的是点 JAR file生成的jar包 invoke调用会出现classnotfound的错误
要先运行 FreemarkerUtil.java 的main方法一次
然后再点Runnable JAR file
配置Launch configuration