16.

【Spring】file: 外部ファイルの読み込み

編集
この記事の要点
  • Spring で外部ファイルを読み込む 5 つの方法
  • ResourceLoader: classpath: / file: / http:// 等プレフィックス対応
  • @Value("classpath:config.json"): Resource 型に注入
  • ResourceUtils.getFile(): java.io.File として取得
  • ClassPathResource: classpath: 専用クラス
  • 本番では jar 内ファイルは getInputStream() 経由が安全(getFile() は jar 内で動かない)

 

file: / classpath: プレフィックス

プレフィックス用途
classpath:クラスパス (jar 内含む)classpath:config/app.json
classpath*:複数 jar から検索classpath*:META-INF/spring.factories
file:ファイルシステムfile:/etc/myapp/config.json
http:// / https://リモート URLhttps://example.com/config.json
url:generic URLurl:ftp://...
プレフィックスなし相対パス(カレントディレクトリ)config/app.json

方法 1: @Value で Resource 注入

@Service
public class ConfigService {

    @Value("classpath:config/app.json")
    private Resource configResource;

    @Value("file:/etc/myapp/secret.key")
    private Resource secretResource;

    public String readConfig() throws IOException {
        try (InputStream is = configResource.getInputStream();
             BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
            return reader.lines().collect(Collectors.joining("\n"));
        }
    }
}

方法 2: ResourceLoader 注入

@Service
public class FileService {

    @Autowired
    private ResourceLoader resourceLoader;

    public String loadFile(String path) throws IOException {
        Resource resource = resourceLoader.getResource(path);
        // path: "classpath:config/app.json"
        //       "file:/etc/myapp/data.txt"
        //       "https://example.com/data.json"

        try (InputStream is = resource.getInputStream()) {
            return new String(is.readAllBytes(), StandardCharsets.UTF_8);
        }
    }
}

方法 3: ClassPathResource 直接

// classpath: のみ
ClassPathResource resource = new ClassPathResource("config/app.json");

try (InputStream is = resource.getInputStream()) {
    ObjectMapper mapper = new ObjectMapper();
    AppConfig config = mapper.readValue(is, AppConfig.class);
}

// Path 指定 (Spring Boot 標準の resources/ フォルダ基準)
ClassPathResource resource = new ClassPathResource("/templates/email.html");

方法 4: ResourceUtils.getFile()

// java.io.File として取得 (開発時のみ動く、jar 内では NG)
try {
    File file = ResourceUtils.getFile("classpath:config/app.json");
    String content = Files.readString(file.toPath());
} catch (FileNotFoundException e) {
    // jar 内では FileNotFoundException
    // → 本番では getInputStream() 推奨
}

// 安全な書き方
Resource resource = new ClassPathResource("config/app.json");
String content;
try (InputStream is = resource.getInputStream()) {
    content = new String(is.readAllBytes(), StandardCharsets.UTF_8);
}

方法 5: PropertyPlaceholderConfigurer / @PropertySource

@Configuration
@PropertySource("classpath:custom.properties")
@PropertySource(value = "file:${EXTERNAL_CONFIG:/etc/myapp/config.properties}",
                ignoreResourceNotFound = true)
public class AppConfig { }

方法 6: spring.config.import (Spring Boot 2.4+)

# application.yml
spring:
  config:
    import:
      - classpath:custom.properties
      - file:/etc/myapp/override.yml
      - optional:configserver:http://config-server
      - vault://

用途別の選び方

用途推奨
プロパティ設定読込application.properties + @Value
テンプレート / 静的ファイル@Value("classpath:templates/...")
外部設定ファイル(環境別)spring.config.import
暗号化された秘密情報Vault / AWS Secrets Manager
大きなデータファイルfile: + StreamingResponseBody

InputStream vs File

// ✅ jar 内・ファイルシステム両方 OK
Resource resource = new ClassPathResource("config/app.json");
try (InputStream is = resource.getInputStream()) {
    // 処理
}

// ❌ jar 内では動かない (FileNotFoundException)
File file = ResourceUtils.getFile("classpath:config/app.json");

// 一時ファイルに展開する例
Resource resource = new ClassPathResource("template.docx");
Path tempFile = Files.createTempFile("template", ".docx");
try (InputStream is = resource.getInputStream()) {
    Files.copy(is, tempFile, StandardCopyOption.REPLACE_EXISTING);
}
// tempFile に対して通常の File API が使える

具体例: テンプレートファイル読込

// resources/templates/email_welcome.html を読む
@Service
public class EmailService {

    @Value("classpath:templates/email_welcome.html")
    private Resource welcomeTemplate;

    public String renderWelcomeEmail(String userName) throws IOException {
        try (InputStream is = welcomeTemplate.getInputStream()) {
            String template = new String(is.readAllBytes(), StandardCharsets.UTF_8);
            return template.replace("{{name}}", userName);
        }
    }
}

具体例: 外部 JSON 設定

// 開発: classpath、本番: 外部ファイル
@Configuration
public class ExternalConfig {

    @Value("${myapp.config.path:classpath:config/default.json}")
    private Resource configResource;

    @Bean
    public AppSettings appSettings() throws IOException {
        try (InputStream is = configResource.getInputStream()) {
            return new ObjectMapper().readValue(is, AppSettings.class);
        }
    }
}

# application.properties
myapp.config.path=file:/etc/myapp/production.json
# または環境変数: MYAPP_CONFIG_PATH=...

テスト時の差し替え

@SpringBootTest
@TestPropertySource(properties = "myapp.config.path=classpath:config/test.json")
class MyServiceTest { ... }

// または application-test.yml
myapp:
  config:
    path: classpath:config/test.json

関連記事

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. インストール(eclipseプラグイン)
  2. クイックスタート
  3. プロジェクトの作成
  4. Spring Bootプロジェクトの作成
  5. Spring Bootプロジェクトの実行
  6. Spring BootでHello World!
  7. アノテーション一覧
  8. DB接続設定からエンティティおよびリポジトリの作成、値の取得まで(JPA編)
  9. DB接続設定や値の取得(JdbcTemplate編)
  10. ビューから値をモデルに格納しコントローラーで受け取る方法
  11. コントローラーにてモデルに値を格納してビューに渡す方法
  12. テンプレートエンジン
  13. ModelとModelAndViewの違い
  14. AOPの使用方法
  15. classpath: 内部ファイルの読み込み
  16. file: 外部ファイルの読み込み
  17. CSVファイルアップロード方法(Ajax)
  18. CSVファイルダウンロード方法(Ajax)
  19. Spring Bootプロジェクトのビルドと本番環境へのデプロイ方法(内部tomcat使用)
  20. Application.propertiesの環境依存設定の分割方法
  21. JPAにおけるEntityManagerの取得方法
  22. JPAにおけるjava.sql.Connectionの取得方法
  23. エラー一覧
  24. jarの引数を受け取る方法
  25. Spring BootでGmailからメール送信
  26. 複数のDBに接続する設定(Spring Boot & JPA編)
  27. ポート番号の変更
  28. Basic認証の実装と特定のURLに限定する方法
  29. Spring SecurityのBasic認証の無効化
  30. 独自のエラーページを定義する方法
  31. プロパティファイルの値やjar実行時の引数を取得する方法