栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

基于maven,如何将额外的文件打包到jar包中?

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

基于maven,如何将额外的文件打包到jar包中?

1. 絮絮叨叨
  • 自从梳理清楚了与Java文件有关的输入/输出流,现在读取或写入文件基本都不需要上网查资料了,简直磨刀不误砍柴工~ 
  • 感兴趣的,可以查看本人之前的博客:基于文件的java输入/输出流
2. 本地执行Java代码以读取文件
  • 现在有个需求:读取countries文件,计算世界上有多少个国家

  • 创建maven项目,编写代码、本地运行,那是溜溜的,几下就完成了

    // 其他import省略,只展示sl4j的
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class CountriesTest {
        private static final Logger logger = LoggerFactory.getLogger(CountriesTest.class);
    
        public static void main(String[] args) {
            try {
                CountriesTest test = new CountriesTest();
                test.countCountries1();
            } catch (IOException e) {
                logger.error("读取文件失败", e);
            }
        }
    
        
        public void countCountries1() throws IOException {
            // 获取文件目录
            String filePath = this.getClass().getResource("/").getPath().replace("/target/classes/", "");
            logger.info("开始从指定目录读取文件, {} ...", filePath);
            try (BufferedReader reader = new BufferedReader(new FileReader(filePath + "/countries"))) {
                int count = 0;
                String country = reader.readLine();
                while (country != null) {
                    count++;
                    // 获取下一个国家
                    country = reader.readLine();
                }
                logger.info("There are {} countries in the world", count);
            }
        }
    }
    
  • 其中,slf4j的maven依赖为

    
    
        org.slf4j
        slf4j-api
        1.7.30
    
    
        ch.qos.logback
        logback-classic
        1.2.3
    
    
  • countries文件,放在maven模块的父目录下:

  • countries文件的内容,是从网页上粘贴的,部分内容如下:

    Afghanistan
    Albania
    Algeria
    Andorra
    
3. 以jar包的形式执行程序 3.1 打包后执行失败
  • 现在需求升级:将代码打包成jar包,放到服务器上执行

  • 这也很简单,一个打包命令mvn clean package就搞定

  • 结果到服务器上执行时,却报错了。

  • 通过对比代码,发现如下代码存在空指针问题

    String filePath = this.getClass().getResource("/").getPath().replace("/target/classes/", "");
    
  • 自己解压缩对应jar包,也没有在jar包里面找到countries文件。所以,即使文件目录正确,文件不存在,也会读取失败 

3.2 将文件放到resources目录
  • 灵机一动,想到Java项目中还有个src/main/resources目录,

  • Java Web项目中很多配置文件都是放在这里面的,打包时,好像也没有做什么额外的配置,最后还能读取这些文件

  • 抱着试一试的心理,将countries文件移动到了resources目录

  • 然后参考博客:java项目中获得resources目录下的文件或图片,直接以文件流的形式读取resources目录下的countries文件

  • 最终完整的代码如下:

    public class CountriesTest {
        private static final Logger logger = LoggerFactory.getLogger(CountriesTest.class);
    
        public static void main(String[] args) {
            try {
                CountriesTest test = new CountriesTest(); 
                test.countCountries2();
            } catch (IOException e) {
                logger.error("读取文件失败", e);
            }
        }
    
        
        public void countCountries2() throws IOException {
            logger.info("开始从resources目录读取文件 ...");
            // 获取resources下的文件资源
            InputStream in = getClass().getResourceAsStream("/countries");
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
                int count = 0;
                String country = reader.readLine();
                while (country != null) {
                    count++;
                    // 获取下一个国家
                    country = reader.readLine();
                }
                logger.info("There are {} countries in the world", count);
            } catch (IOException e) {
                throw e;
            }
        }
    }
    
  • 重新打包后,成功读取文件 

  • 同事,jar的根目录下出现了countries文件 —— 说明countries文件被成功打包

4. maven resources plugin 4.1 考虑将文件放到其他地方
  • 将文件放在resources目录可以自动打包,如果放到其他层级呢?

  • 下面是笔者的一些试验:

    目录是否ok是否打包
    src/main/java 目录failedNo
    src/main/resources/files目录ok,需要将文件路径更新为InputStream in = getClass().getResourceAsStream("/files/countries");Yes,在files/目录下
    src/files目录failedNo
4.2 指定resources目录
  • 通过网上查阅资料,发现maven resources plugin,可以指定resources目录

  • 按照官网描述,默认的resources目录为src/main/resources,可以通过如下方式在标签中指定resources目录

    
      
        resource1
      
      
        resource2
      
      
        resource3
      
    
    
  • 以将countries文件放到src/main/java 目录为例,配置如下:

    
        
            src/main/java
        
        
        
            src/main/resources
        
    
    
4.3 其他一些高级配置 4.3.1 指定或排除文件
  • 在resources目录下,有各种类型的文件,只有某些文件在文件运行时是需要的

  • 这时,可以通过或指定或排除文件,详情参考官网:Including and excluding files and directories

    
        
            src/main/java
            
            
                ***.bmp
                ...
            
        
    
    
4.3.2 更新文件中的值
  • 文件中,某些变量需要在编译时更新。如hello.txt中,包含${name}

    Hello ${name}
    
  • 可以通过开启filtering属性,将${name}更新为实际值


    src/main/resources
    
    true

  • 而${name}的来源主要有三种,具体参考官网:Filtering
    • maven自带的属性,如${basedir}、${name},可以参考作者之前的博客:10. maven属性,或者网上查阅资料
    • 执行maven命令是,通过-Dxxx传入的值,类似mvn resources:resources -Dname="world"
    • 自定义的property,可以放在pom文件中,也可以使用单独的.properties文件存储
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1014125.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号