我正在使用 Spring Boot,我想要获取资源。
这是我的目录结构:
├───java
│ └───...
├───resources
│ └───files
│ ├───file1.txt
│ ├───file2.txt
│ ├───file3.txt
│ └───file4.txt
我正在尝试获取
files
目录中的资源。以下是我为访问这些文件所做的操作:
@Autowired
private ResourceLoader resourceLoader;
...
Stream<Path> walk = Files.walk(Paths.get(resourceLoader.getResource("classpath:files/").getURI()));
当文件位于
target
目录中时,这可以在本地运行,但是当我从 JAR 文件运行它时找不到这些文件。我该如何解决?我已经检查过这些文件确实存在于位于 BOOT-INF/classes/files
下的 jar 中。
以下是 maven 如何构建并将资源复制到 JAR 中(我不希望 .txt 文件被过滤):
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>**/*.txt</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>**/*.txt</include>
</includes>
</resource>
</resources>
您可以尝试使用以下代码来读取文件吗?
ResourcePatternResolver resourcePatResolver = new PathMatchingResourcePatternResolver();
Resource[] AllResources = resourcePatResolver.getResources("classpath*:files/*.txt");
for(Resource resource: AllResources) {
InputStream inputStream = resource.getInputStream();
//Process the logic
}
这不是您所编写的代码的确切解决方案,但它将给出有关要阅读的资源的概述。
其他人也遇到了与您相同的问题,他们按照 Sambit 的建议将 ResourceLoader 与 ResourcePatternResolver 结合起来找到了解决方案。请参阅此处查看相同问题的答案:https://stackoverflow.com/a/49826409/6777695
下面的示例代码在基于本地 Windows 的开发环境中读取/加载配置为位于 /src/main/resources 项目路径下的 rules/ 文件夹一部分的 Drools 文件,而在基于 Unix 的情况下从应用程序 jar 读取/加载生产环境。
在本地 Windows 开发环境中,使用 org.springframework.core.io.support.ResourcePatternUtils.getResourcePatternResolver 时,加入了使用 java.lang.ClassLoader.getResource(String name) 方法读取/加载文件的方法(ResourceLoader resourcesLoader) 返回 org.springframework.core.io.support.ResourcePatternResolver.getResources(String locationPattern) 部署在基于 Linux 的生产环境中时从应用程序 jar 中读取/加载文件的方法。
Drools 配置
/**
* @author dinesh.lomte
*/
package com.dl.questioneries.rules.api.config;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.runtime.KieContainer;
import org.kie.internal.io.ResourceFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.ResourcePatternUtils;
import com.dl.questioneries.rules.api.exception.SystemException;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Configuration
public class DroolsConfiguration {
private final KieServices kieServices = KieServices.Factory.get();
private ResourceLoader resourceLoader;
/**
*
* @param resourceLoader
*/
@Autowired
public DroolsConfiguration(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
/**
*
* @return
* @throws SystemException
*/
@Bean
public KieContainer kieContainer() throws SystemException {
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
File[] files =
System.getProperty("os.name").contains("Windows")
? loadResourcesOfRulesFromLocalSystem()
: loadResourcesOfRulesFromJar();
if (files == null || files.length == 0) {
String message = "Failed to load the '.drl' files located under resources specific rules folder.";
log.error(message);
throw new SystemException(
"SYS_ERROR_00001", message, new Exception(message));
}
for (File file : files) {
kieFileSystem.write(ResourceFactory.newFileResource(file));
}
log.info("Loaded the configured rule files successfully.");
KieBuilder Kiebuilder = kieServices.newKieBuilder(kieFileSystem);
Kiebuilder.buildAll();
return kieServices.newKieContainer(
kieServices.getRepository().getDefaultReleaseId());
}
/**
*
* @return
*/
private File[] loadResourcesOfRulesFromJar() {
log.info("Loading the configured rule files from Jar.");
Resource[] resources = null;
List<File> files = new ArrayList<>();
try {
resources = ResourcePatternUtils
.getResourcePatternResolver(resourceLoader)
.getResources("classpath*:rules/*.drl");
InputStream inputStream = null;
File file = null;
for (Resource resource : resources) {
try {
inputStream = resource.getInputStream();
file = File.createTempFile(
resource.getFilename().substring(
0, resource.getFilename().length() - 4),
".drl");
FileUtils.copyInputStreamToFile(inputStream, file);
} finally {
inputStream.close();
}
log.info("'{}'", resource.getFilename());
files.add(file);
}
} catch (IOException ioException) {
String message = new StringBuilder(
"Failed to load the '.drl' files located under resources specific rules folder.")
.append(ioException.getMessage()).toString();
log.error(message, ioException);
throw new SystemException(
"SYS_ERROR_00001", message, ioException);
}
return (File[]) files.toArray(new File[files.size()]);
}
/**
*
* @return
*/
private File[] loadResourcesOfRulesFromLocalSystem() {
log.info("Loading the configured rule files from local system.");
try {
File files = new File(
getClass().getClassLoader().getResource("rules/").getPath());
return files.listFiles();
} catch (Exception exception) {
String message = new StringBuilder(
"Failed to load the '.drl' files located under resources specific rules folder.")
.append(exception.getMessage()).toString();
log.error(message, exception);
throw new SystemException(
"SYS_ERROR_00001", message, exception);
}
}
}
控制器
/**
* @author dinesh.lomte
*/
package com.dl.questioneries.rules.api.controller;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.dl.questioneries.rules.api.model.Question;
@RestController
public class QuestioneriesRulesController {
@Autowired
private KieContainer kieContainer;
/**
*
* @param question
* @return
*/
@PostMapping(path = "/getQuestion",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public Question fetchQuestion(@RequestBody Question question) {
KieSession kieSession = kieContainer.newKieSession();
kieSession.insert(question);
kieSession.fireAllRules(1);
return question;
}
}