我有一个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文件使用。
答案 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文件只是应用程序的一部分,并且应该处理一些配置属性,则有不同的方法:
在服务器(例如Servlet)上创建一些动态端点,该端点将根据请求动态返回其所需的配置,然后浏览器将仅调用Servlet并获得结果。采用这种方法(就像您使用的方法一样,您创建的工件仍然取决于运行的环境并不太好)
从外部保留配置属性(在文件系统中,甚至在更高级的情况下,请使用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;
}
}