春天,在应用程序启动期间复制文件

时间:2018-07-24 04:10:25

标签: java spring

我有一个Spring Web应用程序,我需要在应用程序启动时将一个文件的内容复制到另一个文件。

@Component
public class BootStartUp implements ApplicationListener<ContextRefreshedEvent> {

@Override
public void onApplicationEvent(final ContextRefreshedEvent event) {

  File sourceFile = new File(getClass().getClassLoader()
  .getResource("app_dev.json").getFile()); // Present in src/main/resources folder

  // Getting null pointer exception here
  File destFile = new File(getClass().getClassLoader()
  .getResource("AppConfig.json").getFile());  // Present in src/main/webapp folder
}

因此,基本上,我正在尝试从资源文件复制一些属性到webapp文件夹中的文件,该文件将在应用程序加载时由UI文件使用。

2 个答案:

答案 0 :(得分:2)

src / main / * 通常仅存在于源代码中,而在运行时则不存在。

Spring是仅用于运行时的框架,因此在加载时,工件(在这种情况下为WAR)已经构建并打包,因此依靠 src / main / * 为时已晚>东西

WAR具有明确定义的布局,因此,我建议首先考虑“ WAR”布局并检查路径。只需使用可以读取ZIP归档文件(如WinRAR)并进行探索的任何工具打开准备好的WAR。

如果您是从IDE中运行内容,则在某些情况下,src / main / resources文件夹甚至可能存在并且可以从类路径访问,但实际上(在实际生产部署中)它不会存在。 / p>

在此我要强调的另一点是,打包并部署WAR后,应该将其视为只读工件,这意味着在运行时在WAR内部复制文件可能不是一个好主意。

通常,Web容器(Tomcat,Jetty等)将WAR解压缩到某种临时目录中并从那里进行加载,您将永远不知道此目录的路径,它在运行时中始终会更改。

因此,假设UI文件只是应用程序的一部分,并且应该处理一些配置属性,则有不同的方法:

  1. 在服务器(例如Servlet)上创建一些动态端点,该端点将根据请求动态返回其所需的配置,然后浏览器将仅调用Servlet并获得结果。采用这种方法(就像您使用的方法一样,您创建的工件仍然取决于运行的环境并不太好)

  2. 从外部保留配置属性(在文件系统中,甚至在更高级的情况下,请使用Consul等配置服务器,d.spring-cloud-config等),并保持WAR环境独立。这是对第一种方法的补充,但消除了对环境的依赖

答案 1 :(得分:2)

要从webapp目录中读取文件,请使用ResourceLoder

import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;

@Component
public class StartupHousekeeper implements ResourceLoaderAware {

    private ResourceLoader resourceLoader;

    @EventListener(ContextRefreshedEvent.class)
    public void contextRefreshedEvent() {
        try {

        // Read file from src/main/resources folder
        File sourceFile = new File(getClass().getClassLoader()
                .getResource("app_dev.json").getFile());  

        // Read file from src/main/webapp folder
        Resource resource = resourceLoader.getResource("file:webapp/AppConfig.json");
        File file=  resource.getFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

}