SpringBoot項目中resources文件讀取實踐
在 Spring Boot 項目中,resources 目錄承載著大量的關(guān)鍵資源,如配置文件、模板文件、腳本資源、數(shù)據(jù)文件等。而如何以合適的方式高效、安全地讀取這些資源,往往是開發(fā)者繞不過的關(guān)鍵環(huán)節(jié)。
不同的資源加載方式有不同的適用場景和底層機制,如果使用不當,不僅可能導(dǎo)致資源讀取失敗,還可能影響程序的可移植性和擴展性。
本文將為你系統(tǒng)性地講解 Spring Boot 中讀取 resources 文件的 9 種主流方式,并在最后附上一套完整的控制器 Demo 示例,集中展示這些方式在實際項目中的統(tǒng)一實現(xiàn),幫助你在開發(fā)中快速定位最適合的資源加載方案。
資源讀取的 9 大方式概覽
我們先逐一列出每種方式的核心思路與適用場景。
1、ClassLoader.getResourceAsStream()
—— 通用類加載器讀取方式
說明:以類加載器為起點,查找資源路徑。
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("config/sample.txt");- 不依賴 Spring,適用于任意 Java 項目;
- 路徑從
classpath根路徑開始,不需要加/。
2、Class.getResourceAsStream()
—— 相對于類路徑加載資源
說明:當前類對象的路徑定位方式,適合讀取與類位于同一包下的資源。
InputStream inputStream = getClass().getResourceAsStream("/config/sample.txt");- 以
/開頭則從根路徑定位; - 相對路徑時以類的包路徑為基準。
3、使用 Spring 的 ResourceLoader
說明:借助 Spring 提供的通用資源加載抽象,可讀取 classpath、file、http 等協(xié)議資源。
@Resourceprivate ResourceLoader resourceLoader;
4、使用 ResourceUtils.getFile()
說明:用于將 classpath 路徑資源轉(zhuǎn)為 File 對象,適合需要文件路徑的場景。
File file = ResourceUtils.getFile("classpath:config/sample.txt");5、使用 ApplicationContext.getResource()
說明:通過上下文注入加載資源,與 ResourceLoader 類似。
@Resourceprivate ApplicationContext context;
6、使用 ServletContext.getResourceAsStream()
說明:用于傳統(tǒng) Servlet 模型,從 Web 路徑中獲取資源文件。
@Resourceprivate ServletContext servletContext;
7、使用 Java IO 的 File
說明:適用于讀取項目中的真實文件,路徑為實際操作系統(tǒng)路徑。
File file = new File("src/main/resources/config/sample.txt");8、使用 Java NIO 的 Paths 和 Files
說明:使用 Java 8 的現(xiàn)代化文件操作接口,線程安全且效率更高。
Path path = Paths.get("src/main/resources/config/sample.txt");9、使用 Spring 的 ClassPathResource
說明:Spring 原生支持 classpath 路徑加載,簡單快捷。
ClassPathResource resource = new ClassPathResource("config/sample.txt");統(tǒng)一完整代碼實現(xiàn)示例
我們將在一個 Spring Boot 控制器中統(tǒng)一實現(xiàn)這 9 種方式,以 /resource/read/{method} 接口形式暴露,讓你一目了然。
文件路徑準備
請在 src/main/resources/config/sample.txt 文件中放置如下測試內(nèi)容:
這是一個用于演示讀取 resources 文件的示例文本。
控制器實現(xiàn):com.icoderoad.resources.controller.ResourceReadController.java
package com.icoderoad.resources.controller;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Controller;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import java.io.*;
import java.nio.file.*;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/resource/read")
public class ResourceReadController {
@Autowired
private ResourceLoader resourceLoader;
@Autowired
private ApplicationContext applicationContext;
@Autowired
private ServletContext servletContext;
private final String filePath = "config/sample.txt";
@GetMapping("/{method}")
public Map<String, Object> readFile(@PathVariable String method) {
Map<String, Object> result = new HashMap<>();
try {
String content = switch (method) {
case "classloader" -> readByClassLoader();
case "class" -> readByClass();
case "loader" -> readByResourceLoader();
case "utils" -> readByResourceUtils();
case "context" -> readByApplicationContext();
case "servlet" -> readByServletContext();
case "file" -> readByFile();
case "nio" -> readByNio();
case "classpath" -> readByClassPathResource();
default -> "Unsupported method!";
};
result.put("method", method);
result.put("content", content);
} catch (Exception e) {
result.put("error", e.getMessage());
}
return result;
}
private String readByClassLoader() throws IOException {
try (InputStream in = getClass().getClassLoader().getResourceAsStream(filePath)) {
return streamToString(in);
}
}
private String readByClass() throws IOException {
try (InputStream in = getClass().getResourceAsStream("/" + filePath)) {
return streamToString(in);
}
}
private String readByResourceLoader() throws IOException {
org.springframework.core.io.Resource resource = resourceLoader.getResource("classpath:" + filePath);
try (InputStream in = resource.getInputStream()) {
return streamToString(in);
}
}
private String readByResourceUtils() throws IOException {
File file = ResourceUtils.getFile("classpath:" + filePath);
try (InputStream in = new FileInputStream(file)) {
return streamToString(in);
}
}
private String readByApplicationContext() throws IOException {
org.springframework.core.io.Resource resource = applicationContext.getResource("classpath:" + filePath);
try (InputStream in = resource.getInputStream()) {
return streamToString(in);
}
}
private String readByServletContext() throws IOException {
// 僅適用于傳統(tǒng)部署模式,如 war 包放入 Tomcat 時
try (InputStream in = servletContext.getResourceAsStream("/WEB-INF/classes/" + filePath)) {
return streamToString(in);
}
}
private String readByFile() throws IOException {
File file = new File("src/main/resources/" + filePath);
try (InputStream in = new FileInputStream(file)) {
return streamToString(in);
}
}
private String readByNio() throws IOException {
Path path = Paths.get("src/main/resources/" + filePath);
try (InputStream in = Files.newInputStream(path)) {
return streamToString(in);
}
}
private String readByClassPathResource() throws IOException {
ClassPathResource resource = new ClassPathResource(filePath);
try (InputStream in = resource.getInputStream()) {
return streamToString(in);
}
}
private String streamToString(InputStream in) throws IOException {
return new String(FileCopyUtils.copyToByteArray(in));
}
}使用方式說明
| 請求路徑 | 對應(yīng)加載方式 |
|---|---|
| /resource/read/classloader | ClassLoader.getResourceAsStream() |
| /resource/read/class | Class.getResourceAsStream() |
| /resource/read/loader | ResourceLoader |
| /resource/read/utils | ResourceUtils.getFile() |
| /resource/read/context | ApplicationContext.getResource() |
| /resource/read/servlet | ServletContext.getResourceAsStream() |
| /resource/read/file | new File() + FileInputStream |
| /resource/read/nio | Paths + Files |
| /resource/read/classpath | ClassPathResource |
總結(jié)
在本文中,我們不僅系統(tǒng)講解了 Spring Boot 項目中讀取 resources 目錄下文件的 9 大方式,還構(gòu)建了一個完整的統(tǒng)一控制器 Demo,集中展示它們在實際項目中的使用方式。你可以根據(jù)以下建議進行選擇:
推薦方式(通用性 + 簡潔性):
ClassLoader.getResourceAsStream()ClassPathResourceResourceLoader
特定場景方式(依賴文件路徑、Web環(huán)境):
File/Paths/ServletContext
理解并熟練掌握這些方式,將極大提高你在 Spring Boot 項目中處理靜態(tài)資源的靈活性與穩(wěn)定性,特別是在構(gòu)建插件機制、配置中心、文件服務(wù)等系統(tǒng)中。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
java.sql.SQLException問題解決以及注意事項
這篇文章主要給大家介紹了關(guān)于java.sql.SQLException問題解決以及注意事項的相關(guān)資料,這個問題其實很好解決,文中通過圖文將解決的辦法介紹的很詳細,需要的朋友可以參考下2023-07-07
從try-with-resources到ThreadLocal,優(yōu)化你的代碼編寫方式
這篇文章主要為大家介紹了從try-with-resources到ThreadLocal,優(yōu)化代碼的編寫方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-04-04
SpringBoot+Mybatis項目使用Redis做Mybatis的二級緩存的方法
本篇文章主要介紹了SpringBoot+Mybatis項目使用Redis做Mybatis的二級緩存的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-12-12
SpringBoot Security整合JWT授權(quán)RestAPI的實現(xiàn)
這篇文章主要介紹了SpringBoot Security整合JWT授權(quán)RestAPI的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-11-11
spring boot利用docker構(gòu)建gradle項目的實現(xiàn)步驟
這篇文章主要給大家介紹了關(guān)于spring boot利用docker構(gòu)建gradle項目的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用spring boot具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧2018-05-05
SpringBoot實現(xiàn)短信驗證碼校驗方法思路詳解
最近做項目遇到這樣的需求,前端是基于BootStrap,html代碼中有BootStrap樣式實現(xiàn)的,具體后臺實現(xiàn)代碼大家通過本文一起學習吧2017-08-08

