LoginSignup
0
0

【java + spring boot】ローカルでファイル添付処理を実装してみた

Last updated at Posted at 2024-02-03

開発環境

  • java 17
  • springboot
  • thymeleaf

やりたいこと

  • ファイル添付を実装(しながら仕組みを学ぶ)
  • ファイル保管場所:ローカル

手順

  1. バックグラウンド側の各ファイル操作処理を実装
  2. フロント側に添付ファイルのインターフェースになるフォームを実装

こちら参考に実装:ファイルのアップロード

※私は適当なjavaアプリがあったため、「アプリケーションクラスを作成する」 から部分的に移植する形で実装。Exceptionなど大体の追加ファイルはとりあえずcommonディレクトリにぶちこみ。

そのまま実装するとエラーになったので補足

ビルドは通るが実行すると失敗

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in com.example.プロジェクト名.common.FileSystemStorageService required a bean of type 'com.example.プロジェクト名.common.StorageProperties' that could not be found.

Action:
Consider defining a bean of type 'com.example.プロジェクト名.common.StorageProperties' in your configuration.

Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.

You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.

直訳

FileSystemStorageService のコンストラクターのパラメーター 0 には、「com.example.プロジェクト名.common.StorageProperties」タイプの Bean が必要でしたが、見つかりませんでした。

つまり、StorageProperties がBeanに登録されていない。

■エラー発生箇所
 FileSystemStorageService.java

@Service
public class FileSystemStorageService implements StorageService {
    private final Path rootLocation;

    @Autowired
    public FileSystemStorageService(StorageProperties properties) { // ← 多分ここ
    

■エラー原因
@Autowiredを付けるとインスタンス処理を spring boot が自動で行ってくれるが、
引数で引用しようとしているStoragePropertiesがBeanに登録されておらず、呼び出せない状態。

@Autowired にインスタンス化を任せることができるのはSpringフレームワークが提供しているDIコンテナに登録されているクラスのみ。
利用したいクラスに@Component,@Controller,@Service,@RepositoryをつけることでDIコンテナへ登録が可能です。...引用1

■解決策
StoragePropertiesクラスに@Componentを付与(ほかにも方法はあるらしい)。

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; // 追加

@Component // 追加:ConfigurationPropertiesを付けたクラスに付けることでBeanに登録する
@ConfigurationProperties("storage") //DIコンテナに登録されたBeanに対してプロパティを設定するためのアノテーション
public class StorageProperties {
    private String location = "upload-dir";
}
...

■その他
場合によってはStorageProperties.locationをget/setすためにgetter/setterが必要になる。
Lambok を使用している場合は下記で、使用しない場合は直で実装する必要がある。

import lombok.Getter; // 追加
import lombok.Setter; // 追加
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Getter // 追加
@Setter // 追加
@Component
@ConfigurationProperties("storage")
public class StorageProperties { ...

アプリ起動しファイル添付実行

■添付ファイルが保存された場所

今回は↑に記載した通りStoragePropertiesクラスでファイルデータを保管するロケーションを"upload-dir"と指定している。

public class StorageProperties {
    private String location = "upload-dir";
}

確認するとプロジェクト直下に"upload-dir"が作成され、ファイルアップロードが成功すると添付ファイル名でファイルが生成(※正しくはデータのコピー保存)されている。

【読み解き】実装を調べてみた

...は次回の投稿に

引用リスト

  1. 【Spring】@Autowiredはコンストラクタインジェクションで使おう!
  2. ファイルのアップロード
  3. Spring Bootの@ ConfigurationPropertiesで型安全なプロパティ設定
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0