在Spring Boot中从类路径加载文件
阅读原文时间:2023年07月08日阅读:1

创建Spring Boot Web应用程序时,有时有时需要从类路径中加载文件;war和jar的加载文件格式是不一样的

在下面,您将找到在WARJAR中加载文件的解决方案。

资源加载器

使用Java,您可以使用当前线程的classLoader并尝试加载文件,但是Spring Framework为您提供了更为优雅的解决方案,例如ResourceLoader

您只需要自动连接ResourceLoader,然后调用getResource(„somePath“)方法即可。

在Spring Boot(WAR)中从资源目录/类路径加载文件的示例

在以下示例中,我们从类路径中加载名为GeoLite2-Country.mmdb的文件作为资源,然后将其作为File对象检索。

@Service("geolocationservice")
public class GeoLocationServiceImpl implements GeoLocationService {

private static final Logger LOGGER = LoggerFactory.getLogger(GeoLocationServiceImpl.class);

private static DatabaseReader reader = null;

private ResourceLoader resourceLoader;

@Autowired  
public GeoLocationServiceImpl(ResourceLoader resourceLoader) {  
    this.resourceLoader = resourceLoader;  
}

@PostConstruct  
public void init() {  
    try {  
        LOGGER.info("GeoLocationServiceImpl: Trying to load GeoLite2-Country database...");

        Resource resource = resourceLoader.getResource("classpath:GeoLite2-Country.mmdb");  
        File dbAsFile = resource.getFile();

        // Initialize the reader  
        reader = new DatabaseReader  
                    .Builder(dbAsFile)  
                    .fileMode(Reader.FileMode.MEMORY)  
                    .build();

        LOGGER.info("GeoLocationServiceImpl: Database was loaded successfully.");

    } catch (IOException | NullPointerException e) {  
        LOGGER.error("Database reader cound not be initialized. ", e);  
    }  
}

@PreDestroy  
public void preDestroy() {  
    if (reader != null) {  
        try {  
            reader.close();  
        } catch (IOException e) {  
            LOGGER.error("Failed to close the reader.");  
        }  
    }  
}  

}

在Spring Boot(JAR)中从资源目录/类路径加载文件的示例

如果您想从Spring Boot JAR中的 classpath加载文件,则必须使用该resource.getInputStream()方法将其作为InputStream检索。如果尝试使用resource.getFile()该方法,则会收到错误消息,因为Spring尝试访问文件系统路径,但无法访问JAR中的路径。

@Service("geolocationservice")
public class GeoLocationServiceImpl implements GeoLocationService {

private static final Logger LOGGER = LoggerFactory.getLogger(GeoLocationServiceImpl.class);

private static DatabaseReader reader = null;  
private ResourceLoader resourceLoader;

@Inject  
public GeoLocationServiceImpl(ResourceLoader resourceLoader) {  
    this.resourceLoader = resourceLoader;  
}

@PostConstruct  
public void init() {  
    try {  
        LOGGER.info("GeoLocationServiceImpl: Trying to load GeoLite2-Country database...");

        Resource resource = resourceLoader.getResource("classpath:GeoLite2-Country.mmdb");  
        InputStream dbAsStream = resource.getInputStream(); // <-- this is the difference

        // Initialize the reader  
        reader = new DatabaseReader  
                    .Builder(dbAsStream)  
                    .fileMode(Reader.FileMode.MEMORY)  
                    .build();

        LOGGER.info("GeoLocationServiceImpl: Database was loaded successfully.");

    } catch (IOException | NullPointerException e) {  
        LOGGER.error("Database reader cound not be initialized. ", e);  
    }  
}

@PreDestroy  
public void preDestroy() {  
    if (reader != null) {  
        try {  
            reader.close();  
        } catch (IOException e) {  
            LOGGER.error("Failed to close the reader.");  
        }  
    }  
}  

}