• 「问题解决」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

    1.  package com.javalaoniu.blog.utils;
    2.  
    3.  import com.javalaoniu.blog.exception.BlogBusinessException;
    4.  import freemarker.template.Configuration;
    5.  import freemarker.template.Template;
    6.  import org.slf4j.Logger;
    7.  import org.slf4j.LoggerFactory;
    8.  
    9.  import java.io.File;
    10.  import java.io.FileWriter;
    11.  import java.net.URL;
    12.  import java.util.Map;
    13.  
    14.  public class FreemarkerUtil {
    15.  
    16.   private static final Logger LOGGER = LoggerFactory.getLogger(FreemarkerUtil.class);
    17.  
    18.   /**
    19.   * 生成静态html文件
    20.   *
    21.   * @param ftlFile 模板文件
    22.   * @param map 用于模板中的数据
    23.   * @param htmlFile 输出的文件
    24.   */
    25.   public void genHtml(String ftlFile, String htmlFile, Map map) {
    26.   LOGGER.info("ftlFile:{}", ftlFile);
    27.   LOGGER.info("htmlFile:{}", htmlFile);
    28.   try {
    29.   URL resource = this.getClass().getResource(ftlFile);
    30.   File mobanFile = new File(resource.getPath());
    31.   LOGGER.info("模板文件:{}", mobanFile.getPath());
    32.  
    33.   Configuration cfg = new Configuration(Configuration.VERSION_2_3_23);
    34.   cfg.setDirectoryForTemplateLoading(new File(mobanFile.getParent()));
    35.   cfg.setDefaultEncoding("utf-8");
    36.   Template template = cfg.getTemplate(mobanFile.getName());
    37.  
    38.   //生成静态页面
    39.   File outFile = new File(htmlFile);
    40.   if (!outFile.exists()) {
    41.   // 创建目录
    42.   File dir = new File(outFile.getParent());
    43.   dir.mkdirs();
    44.   }
    45.   if (outFile.exists()&&!outFile.isFile()) {
    46.   throw new RuntimeException("输出文件错误,它不是文件");
    47.   }
    48.   LOGGER.info("outFile.getPath:{}", outFile.getPath());
    49.   //String ftlPath = this.getClass().getClassLoader().getResource(ftlFile)
    50.  
    51.   FileWriter fw = new FileWriter(outFile);
    52.   template.process(map, fw);
    53.   LOGGER.info("输出文件:{}", outFile.getPath());
    54.   } catch (Exception e) {
    55.   LOGGER.error("生成静态文件异常:", e);
    56.   throw new BlogBusinessException("生成静态文件异常", e);
    57.   }
    58.   }
    59.  
    60.  }

    修改后源代码:
    这时候传递的ftlFile参数为:help-page.ftl

    1.  package com.javalaoniu.blog.utils;
    2.  
    3.  import com.javalaoniu.blog.exception.BlogBusinessException;
    4.  import freemarker.cache.ClassTemplateLoader;
    5.  import freemarker.template.Configuration;
    6.  import freemarker.template.Template;
    7.  import org.slf4j.Logger;
    8.  import org.slf4j.LoggerFactory;
    9.  
    10.  import java.io.File;
    11.  import java.io.FileWriter;
    12.  import java.util.Map;
    13.  
    14.  public class FreemarkerUtil {
    15.  
    16.   private static final Logger LOGGER = LoggerFactory.getLogger(FreemarkerUtil.class);
    17.  
    18.   /**
    19.   * 生成静态html文件
    20.   *
    21.   * @param ftlFile 模板文件
    22.   * @param map 用于模板中的数据
    23.   * @param htmlFile 输出的文件
    24.   */
    25.   public void genHtml(String ftlFile, String htmlFile, Map map) {
    26.   LOGGER.info("ftlFile:{}", ftlFile);
    27.   LOGGER.info("htmlFile:{}", htmlFile);
    28.   try {
    29.   LOGGER.info("模板文件:{}", ftlFile);
    30.  
    31.   Configuration cfg = new Configuration(Configuration.VERSION_2_3_23);
    32.   //cfg.setDirectoryForTemplateLoading(new File(mobanFile.getParent()));// 打成jar后运行获取到的路径不对
    33.   //cfg.setClassForTemplateLoading(FreemarkerUtil.class, "moban");// 打成jar后运行获取到的路径不对
    34.   cfg.setTemplateLoader(new ClassTemplateLoader(
    35.   this.getClass().getClassLoader(), "/moban"));
    36.   cfg.setDefaultEncoding("utf-8");
    37.   Template template = cfg.getTemplate(ftlFile);
    38.  
    39.   //生成静态页面
    40.   File outFile = new File(htmlFile);
    41.   if (!outFile.exists()) {
    42.   // 创建目录
    43.   File dir = new File(outFile.getParent());
    44.   dir.mkdirs();
    45.   }
    46.   if (outFile.exists()&&!outFile.isFile()) {
    47.   throw new RuntimeException("输出文件错误,它不是文件");
    48.   }
    49.   LOGGER.info("outFile.getPath:{}", outFile.getPath());
    50.   //String ftlPath = this.getClass().getClassLoader().getResource(ftlFile)
    51.  
    52.   FileWriter fw = new FileWriter(outFile);
    53.   template.process(map, fw);
    54.   LOGGER.info("输出文件:{}", outFile.getPath());
    55.   } catch (Exception e) {
    56.   LOGGER.error("生成静态文件异常:", e);
    57.   throw new BlogBusinessException("生成静态文件异常", e);
    58.   }
    59.   }
    60.  
    61.  }
    62.  ​

    鄙人编码十年多,在项目中也积累了一些工具类,很多工具类在每个项目都有在用,很实用。大部分是鄙人封装的,有些工具类是同事封装的,有些工具类已经不记得是ctrl+c的还是自己封装的了,现在有空就会总结项目中大部分的工具类,分享给各位码友。如果文章中涉及的代码有侵权行为请通知鄙人处理。

    计划是先把工具类整理出来,正所谓工欲善其事,必先利其器。项目中不管是普通单体项目还是多模块maven项目或是分布式微服务,一部分功能模块都是可以重用的,工具类模块就是其中之一。

  • 相关阅读:
    基于JAVA上虞烟草物流配送系统计算机毕业设计源码+数据库+lw文档+系统+部署
    干货| 算法工程师常见问题(基础算法篇)
    多级式多传感器信息融合中的状态估计(Matlab代码实现)
    摊牌了,AI外呼是真的好用
    C++ if 语句
    算法整理(二)
    【Logback+Spring-Aop】实现全面生态化的全链路日志追踪系统服务插件「SpringAOP 整合篇」
    resize2fs: New size too large to be expressed in 32 bits
    IDEA插件开发(18)---通知
    基于python的km算法新闻文本分类
  • 原文地址:https://blog.csdn.net/lxn39830435731415926/article/details/126696486