如何在 Spring Boot MVC Web 应用程序中从 META/MANIFEST.MF 读取数据?

2024-02-19

我需要读取 Spring Boot MVC Web 应用程序的 META/MANIFEST.MF 文件中提供的信息,并使用此信息来执行一些业务逻辑。我使用 gradle 将应用程序构建为 war 文件并将其部署到外部 tomcat 中。

我已经尝试过以下方法:

@Configuration
public class AppConfig
{
    @Bean("manifest")
    public java.util.jar.Manifest getManifest() throws IOException
    {
        InputStream inputFile = this.getClass().getClassLoader().getResourceAsStream("META-INF/MANIFEST.MF");
        Manifest manifestObj = new Manifest(inputFile);
        return manifestObj;
    }
}

应用服务.java

@Service
public class AppService
{        
    @Autowired
    @Qualifier("manifest")
    private Manifest manifest;
    
    @PostConstruct
    public String init()
    {
        Attributes mainAttributes = manifest.getMainAttributes();
        String buildNum = mainAttributes.getValue("Build-Number");
        String customPropInfo= mainAttributes.getValue("customPropInfo");
        String systemPrp1= buildNum + "_" + "SomeBusinessInfoLogic1";
        String systemPrp2= customPropInfo+ "_" + "SomeBusinessInfoLogic2";
        //Some Business Logic with these attributes systemPrp, systemPrp2
        logger.info("System Props are updated");
    }
}

我两者都为空buildNum and customPropInfo.

注意:我尝试创建 Manifest bean 类似this https://stackoverflow.com/q/72640712/9145082这是我创建的。根据 @M.Deinum 建议,我在这里创建这个新问题。我也尝试了解决方案here https://stackoverflow.com/questions/3777055/reading-manifest-mf-file-from-jar-file-using-java/3777116#3777116这对我不起作用。

@M.Deinum 建议使用 Spring Boot 的 Actuator Info 端点。但是,当我们想要访问应用程序外部的信息时,此端点非常有用,但我的要求有所不同,因为我需要 MANIFEST.MF 文件中可用的数据来在应用程序内执行某些业务操作。

当我尝试时出现以下错误这个解决方案 https://stackoverflow.com/a/26687713/9145082 "/META-INF/MANIFEST.MF".

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'manifest' defined in class path resource [com/abc/AppConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [java.util.jar.Manifest]: Factory method 'getManifest' threw exception; nested exception is java.lang.NullPointerException: Cannot invoke "java.io.InputStream.read(byte[], int, int)" because "this.in" is null

有人可以帮我从 Spring Boot MVC Web 应用程序的 META/MANIFEST.MF 中读取信息吗?

UPDATE1:当我尝试打印主要属性时,我得到以下主要属性。但问题是当我尝试将战争部署到外部 tomcat 时。

System.out.println("Manifest MainAttributes = " +manifestObj.getMainAttributes().keySet());

Output:

Manifest MainAttributes = [Manifest-Version, Implementation-Title, Automatic-Module-Name, Implementation-Version, Built-By, Spring-Boot-Jar-Type, Build-Jdk-Spec]

UPDATE2:我已更新到 AppService.java 以打印自动装配 Manifest 对象中可用的信息。像下面这样:

@Configuration
public class AppConfig
{
    @Bean("manifest")
    public java.util.jar.Manifest getManifest() throws IOException
    {
        InputStream inputFile = new ClassPathResource("/META-INF/MANIFEST.MF").getInputStream();
        Manifest manifestObj = new Manifest(inputFile);
        System.out.println("Manifest Manifest-Version = " +manifestObj.getMainAttributes().getValue("Manifest-Version"));
        System.out.println("Manifest KeySet = " +manifestObj.getMainAttributes().keySet());
        return manifestObj;
    }
}
@Service
public class AppService
{        
    @Autowired
    @Qualifier("manifest")
    private Manifest manifest;
    
    @PostConstruct
    public String init()
    {
        Attributes mainAttributes = manifest.getMainAttributes();
        mainAttributes.forEach((k,v) -> {
            System.out.println("AppService.init(): Key = "+k+", Value = "+v);
        });
        String buildNum = mainAttributes.getValue("Build-Number");
        String customPropInfo= mainAttributes.getValue("customPropInfo");
        String systemPrp1= buildNum + "_" + "SomeBusinessInfoLogic1";
        String systemPrp2= customPropInfo+ "_" + "SomeBusinessInfoLogic2";
        //Some Business Logic with these attributes systemPrp, systemPrp2
        logger.info("System Props are updated");
    }
}

我在控制台上看到以下输出:

AppService.init(): Key = Implementation-Title, Value = Apache Tomcat Bootstrap
AppService.init(): Key = Implementation-Version, Value = 9.0.12
AppService.init(): Key = Specification-Vendor, Value = Apache Software Foundation
AppService.init(): Key = Specification-Title, Value = Apache Tomcat Bootstrap
AppService.init(): Key = Class-Path, Value = commons-daemon.jar
AppService.init(): Key = Manifest-Version, Value = 1.0
AppService.init(): Key = Main-Class, Value = org.apache.catalina.startup.Bootstrap
AppService.init(): Key = Implementation-Vendor, Value = Apache Software Foundation
AppService.init(): Key = Ant-Version, Value = Apache Ant 1.9.9
AppService.init(): Key = X-Compile-Target-JDK, Value = 1.8
AppService.init(): Key = X-Compile-Source-JDK, Value = 1.8
AppService.init(): Key = Created-By, Value = some xyz
AppService.init(): Key = Specification-Version, Value = 9.0

因此,仅根据上面的输出,我认为 MANIFEST.MF 不是特定于应用程序的,而是来自commons-daemon.jar.


好的 - 问题不在于您“无法从 Spring Boot MVC Web 应用程序中的 META/MANIFEST.MF 读取数据”。相反,问题在于您的代码碰巧正在读取WRONG来自类路径中其他随机 .jar 的 MANIFEST.MF。

一种解决方案可能是使用Jar类加载器 https://docs.oracle.com/javase/tutorial/deployment/jar/jarclassloader.html.

正如 M. Deinum 所建议的,另一种解决方案可能是将您希望检索的属性存储在应用程序属性 https://www.tutorialspoint.com/spring_boot/spring_boot_application_properties.htm(或其他一些“全局”属性文件)而不是 MANIFEST.MF。

还: 我假设您可能正在使用 IDE 来开发您的应用程序(Eclipse、Netbeans 等)。如果你还没有,我会STRONGLY鼓励您熟悉 IDE 的调试器:设置断点、显示变量、单步执行方法调用等的能力。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Spring Boot MVC Web 应用程序中从 META/MANIFEST.MF 读取数据? 的相关文章

  • 如何将 JSpinner 的值设置为特定日期

    我有一个JSpinner我添加到JPanel我想将其时间设置为 GregorianCalendar calendar JSpinner spinner new JSpinner spinner setModel model pom add
  • 如何在log4j的配置文件中为文件附加器提供环境变量路径

    我有一个log4j xml配置文件 和一个RollingFileAppender我需要提供用于存储日志的文件路径 问题是我的代码将作为可运行的 jar 部署在 Unix 机器上 所以如果我传递这样的参数 value logs message
  • 项目缺少所需的注释处理库

    我的 Eclipse IDE 突然在问题视图中显示 xxxx 项目缺少所需的注释处理库 xxxx M2 REPO 中的一些旧 jar 我用谷歌搜索 没有找到任何答案 为什么我的项目使用旧的 jar 以及错误来自哪里 To remove th
  • 如何将现有的 SQLite3 数据库导入 Room?

    好吧 我在桌面上使用 SQLite3 创建了一个只需要读取的某些信息的数据库 我正在制作的应用程序不需要在此表中插入或删除信息 我在 Room 数据库层上做了相当多的谷歌搜索 所有文档都需要在构建应用程序时在 Room 中创建一个新的数据库
  • JTextField 和 JTextArea

    JTextField 和 JTextArea 有什么不同 是否可以在一个班级中使用这两个班级 总之 JTextField 是单行文本字段 而 JTextArea 可以跨越多行 文档中清楚地解释了这些差异 文本区 http docs orac
  • 具有 CRUD 功能的基于 Spring Web 的管理工具

    在 PHP Symfony 世界里有一个工具叫 Sonata Adminhttps sonata project org https sonata project org 基于 AdminLTE 模板 这是一款一体化管理工具 具有登录 菜单
  • 在 Java 中创建 T 的新实例

    在C 中 我们可以定义一个泛型class A
  • 正则表达式在 Velocity 模板中不起作用

    我在 Test java 中尝试过这个 String regex lt s br s s gt String test1 lt br gt System out println test replaceAll regex 但是当我在速度模板
  • LocalDate 减去 period 得到错误的结果

    LocalDate减去一个Period 如 28年1个月27天 得到错误的结果 但减去一个Period 只有天单位 如 10282 天 得到正确的结果 有什么需要注意的吗 public static void main String arg
  • 从 Android 访问云存储

    我一直无法找到任何有关如何从 Android 应用程序使用云存储的具体文档 我确实遇到过这个客户端库 https cloud google com storage docs reference libraries然而 Google Clou
  • 多线程——更快的方法?

    我有一堂有吸气剂的课程getInt 和一个二传手setInt 在某个领域 比如说领域 Integer Int 一个类的一个对象 比如说SomeClass The setInt 这里是同步的 getInt isn t 我正在更新的值Int来自
  • MongoDB java 驱动程序 3.0 在身份验证时无法捕获异常

    我超级卡住o 0 在尝试通过 Java 驱动程序进行身份验证时 存在捕获异常的问题 正如你可能会看到的Throwable类不工作 private MongoClient mongoClient private MongoDatabase m
  • 使用 HTTPServletRequestWrapper 包装请求参数

    我有一个可以验证 授权 REST 调用的过滤器 该过滤器需要访问请求参数 因此我为此编写了一个自定义 HTTPServletRequestWrapper import java util Collections import java ut
  • java swing:向 JTree 项目添加自定义图形按钮

    我想在 JTree 中的项目右侧添加一个带有小图标的附加按钮 这可以做到吗 如果是这样 怎么办 thanks Clamp 你在这方面成功了吗 我想做同样的事情 但很难让 JButton 响应用户 设置渲染器以显示按钮的过程很顺利 但所有鼠标
  • JAXB 编组器无参数默认构造函数

    我想从 java 库中编组一个 java 对象 当使用 JAXB marschaller 编组 java 对象时 我遇到了一个问题 A 类没有无参数默认构造函数 我使用Java Decompiler来检查类的实现 它是这样的 public
  • 在循环中按名称访问变量

    我正在开发一个 Android 项目 并且有很多可绘制对象 这些绘图的名称都类似于icon 0 png icon 1 png icon 100 png 我想将这些可绘制对象的所有资源 ID 添加到整数 ArrayList 中 对于那些不了解
  • 传递 Android DialogFragment 参数时,onCreateDialog 捆绑参数意外为 null

    我正在尝试使用 DialogFragment 在 Android 中显示一个基本对话框 并使用对话框消息的参数 如中所述StackOverflow线程 https stackoverflow com questions 15459209 p
  • 使用自定义比较器在 Java 中创建 SortedMap

    我想创建一个TreeMap在 Java 中具有自定义排序顺序 排序后的键是字符串 需要根据第二个字符进行排序 这些值也是字符串 示例地图 Za FOO Ab Bar 您可以像这样使用自定义比较器 Comparator
  • HTTPS 请求仅在 iOS、Ionic 2 上失败

    我有一个Ionic 2调用一个应用程序Spring Boot用于向其他设备发送推送通知的 API API 配置为 HTTPS The API POST请求适用于一切except iOS 我在服务器上的 SSL 证书是自签名的 也许就是这样
  • Jackson 反序列化相当于 @JsonUnwrapped 吗?

    假设我有以下课程 public class Parent public int age JsonUnwrapped public Name name 生成 JSON age 18 first Joey last Sixpack 我如何将其反

随机推荐