「問題解決」java web項目打成jar包運行后工具類無法讀取模板文件的解決方法
介紹語
本號主要是Java常用關鍵技術點,通用工具類的分享;以及springboot+springcloud+Mybatisplus+druid+mysql+redis+swagger+maven+docker等集成框架的技術分享;datax、kafka、flink等大數據處理框架的技術分享。文章會不斷更新,歡迎碼友關注點贊收藏轉發!
望各位碼友點擊關注,沖1000粉。后面會錄制一些視頻教程,圖文和視頻結合,比如:圖書介紹網站系統、搶購系統、大數據中臺系統等。技術才是程序猿的最愛,碼友們沖啊
如果碼友覺得代碼太長,可以從頭到尾快速掃射一遍,了解大概即可。覺得有用后再轉發收藏,以備不時之需。
正文:
項目目錄結構如下:
我在開發博客系統的的時候,需要使用工具類FreemarkerUtil獲取ftl模板文件生成html文件, idea本地運行正常,freemarker正常獲取到模板并生成靜態文件,如下圖:
打包成jar包之后在服務器上運行,報如下問題:
java.io.FileNotFoundException: file:/home/myblog-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/moban does not exist.
百度后大悟,打包成jar包時,不能使用new File()方式獲取jar包中的文件,需要用流的方式獲取。所以修改代碼后,在本地idea運行正常,服務器運行也正常了。
工具類源碼:
修改前源代碼:
這時候傳遞的ftlFile參數為:/moban/help-page.ftl
package com.javalaoniu.blog.utils;
import com.javalaoniu.blog.exception.BlogBusinessException;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileWriter;
import java.net.URL;
import java.util.Map;
public class FreemarkerUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(FreemarkerUtil.class);
/**
* 生成靜態html文件
*
* @param ftlFile 模板文件
* @param map 用于模板中的數據
* @param htmlFile 輸出的文件
*/
public void genHtml(String ftlFile, String htmlFile, Map map) {
LOGGER.info("ftlFile:{}", ftlFile);
LOGGER.info("htmlFile:{}", htmlFile);
try {
URL resource = this.getClass().getResource(ftlFile);
File mobanFile = new File(resource.getPath());
LOGGER.info("模板文件:{}", mobanFile.getPath());
Configuration cfg = new Configuration(Configuration.VERSION_2_3_23);
cfg.setDirectoryForTemplateLoading(new File(mobanFile.getParent()));
cfg.setDefaultEncoding("utf-8");
Template template = cfg.getTemplate(mobanFile.getName());
//生成靜態頁面
File outFile = new File(htmlFile);
if (!outFile.exists()) {
// 創建目錄
File dir = new File(outFile.getParent());
dir.mkdirs();
}
if (outFile.exists()&&!outFile.isFile()) {
throw new RuntimeException("輸出文件錯誤,它不是文件");
}
LOGGER.info("outFile.getPath:{}", outFile.getPath());
//String ftlPath = this.getClass().getClassLoader().getResource(ftlFile)
FileWriter fw = new FileWriter(outFile);
template.process(map, fw);
LOGGER.info("輸出文件:{}", outFile.getPath());
} catch (Exception e) {
LOGGER.error("生成靜態文件異常:", e);
throw new BlogBusinessException("生成靜態文件異常", e);
}
}
}
修改后源代碼:
這時候傳遞的ftlFile參數為:help-page.ftl
package com.javalaoniu.blog.utils;
import com.javalaoniu.blog.exception.BlogBusinessException;
import freemarker.cache.ClassTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileWriter;
import java.util.Map;
public class FreemarkerUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(FreemarkerUtil.class);
/**
* 生成靜態html文件
*
* @param ftlFile 模板文件
* @param map 用于模板中的數據
* @param htmlFile 輸出的文件
*/
public void genHtml(String ftlFile, String htmlFile, Map map) {
LOGGER.info("ftlFile:{}", ftlFile);
LOGGER.info("htmlFile:{}", htmlFile);
try {
LOGGER.info("模板文件:{}", ftlFile);
Configuration cfg = new Configuration(Configuration.VERSION_2_3_23);
//cfg.setDirectoryForTemplateLoading(new File(mobanFile.getParent()));// 打成jar后運行獲取到的路徑不對
//cfg.setClassForTemplateLoading(FreemarkerUtil.class, "moban");// 打成jar后運行獲取到的路徑不對
cfg.setTemplateLoader(new ClassTemplateLoader(
this.getClass().getClassLoader(), "/moban"));
cfg.setDefaultEncoding("utf-8");
Template template = cfg.getTemplate(ftlFile);
//生成靜態頁面
File outFile = new File(htmlFile);
if (!outFile.exists()) {
// 創建目錄
File dir = new File(outFile.getParent());
dir.mkdirs();
}
if (outFile.exists()&&!outFile.isFile()) {
throw new RuntimeException("輸出文件錯誤,它不是文件");
}
LOGGER.info("outFile.getPath:{}", outFile.getPath());
//String ftlPath = this.getClass().getClassLoader().getResource(ftlFile)
FileWriter fw = new FileWriter(outFile);
template.process(map, fw);
LOGGER.info("輸出文件:{}", outFile.getPath());
} catch (Exception e) {
LOGGER.error("生成靜態文件異常:", e);
throw new BlogBusinessException("生成靜態文件異常", e);
}
}
}
?
鄙人編碼十年多,在項目中也積累了一些工具類,很多工具類在每個項目都有在用,很實用。大部分是鄙人封裝的,有些工具類是同事封裝的,有些工具類已經不記得是ctrl+c的還是自己封裝的了,現在有空就會總結項目中大部分的工具類,分享給各位碼友。如果文章中涉及的代碼有侵權行為請通知鄙人處理。
計劃是先把工具類整理出來,正所謂工欲善其事,必先利其器。項目中不管是普通單體項目還是多模塊maven項目或是分布式微服務,一部分功能模塊都是可以重用的,工具類模塊就是其中之一。

浙公網安備 33010602011771號