如何读取jar包内的模板文件作为addSharedFunction()

我只使用了enjoy模块,但是读取jar内的html模板时读取不到,因为jar是作为一个单独的文件存在的,是不能往下寻找目录的,所以有什么办法解决吗?

错误:

Exception in thread "main" java.lang.RuntimeException: File not found : /media/catch/software/projects/VSCodeProjects/banmutang-theme-catch/banmutang-theme-dev-tools-1.0.jar/__layout.html
        at com.jfinal.template.source.FileSource.getContent(FileSource.java:70)
        at com.jfinal.template.EngineConfig.doAddSharedFunction(EngineConfig.java:92)
        at com.jfinal.template.EngineConfig.addSharedFunction(EngineConfig.java:124)
        at com.jfinal.template.Engine.addSharedFunction(Engine.java:248)
        at com.edaoe.Config.init(Config.java:58)
        at com.edaoe.App.main(App.java:21)


评论区

JFinal

2018-09-06 10:37

配置下面的两项:
engine.setSourceFactory(new ClassPathSourceFactory());
engine.setBaseTemplatePath(null);

最后还要注意下面这个问题:
http://www.jfinal.com/share/979

上面这个问题在即将发布的 jfinal 3.5 中已经解决了

Dull

2018-09-06 11:38

这个是其中一个解决办法,但是其实只有layout.html是在jar内,其他模板文件是在jar外,所以希望3.5增加一个JarSource implements ISource来实现jar内文件的读取,读取方法可以参考http://hxraid.iteye.com/blog/483115,我的代码如下
/**
* @author Catch
* @date 2018-09-06 上午10:15
* @description JarSource 用于从jar中加载模板内容
*/
public class JarSource implements ISource {
private static String tplPath;

public JarSource(String templatePath) {
tplPath = templatePath;
}

@Override
public boolean isModified() {
return false;
}

@Override
public String getKey() {
return tplPath;
}

@Override
public StringBuilder getContent() {
InputStream is = this.getClass().getClassLoader().getResourceAsStream(tplPath);
BufferedReader br = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
try {
String temp;
while ((temp=br.readLine() )!= null){
sb.append(temp);
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb;
}

@Override
public String getEncoding() {
return EngineConfig.DEFAULT_ENCODING;
}
}

Dull

2018-09-06 11:39

读取的关键就在 this.getClass().getClassLoader().getResourceAsStream(tplPath);

Dull

2018-09-06 11:40

刚才忘了 @JFinal

JFinal

2018-09-06 12:01

@Dull 何必那么麻烦,功能都在那呢,直接使用:
engine.getTemplate(new ClassPathSource(tplPath));

Engine 中的 getTemplate 重载了很多方便的方法,满足绝大部分需求,即便是不满足,也可以使用 getTemplate(ISource) 方法,这个方法中 ISource 可以让你扩展出从任意地方加载模板

enjoy 内部的 ClassPathSourceFactory、ClassPathSource 不仅仅是可以读取 jar 包内的模板,还同时可以读取 class path 下面的模板,所谓的 class path 下面的模板就是你的 JVM 启动时生效的 class path,通常是下面的这种路径:
WEB-INF/classes
target/classes
bin

总之这个 class path 是 JVM 启动时去找 class 文件的地方

JFinal

2018-09-06 12:02

enjoy 中的所有 getTemplate 方法,本质都是从 getTemplate(ISource source) 扩展出来的,你也可以扩展。

例如扩展出一个 DbSource 从数据库中读取模板,扩展出 NetSource 从网络上读取模板

Dull

2018-09-06 13:40

恩恩,原来有,没注意到,给力

JFinal

2018-09-06 15:28

@Dull enjoy 中已经存在的 ClassPathSource 已经包含了你前面实现的 JarSource 功能,直接用就可以了,无需扩展

热门反馈

扫码入社