質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.09%

AWS S3でプロフィール画像をアップロード、ダウンロードしたい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,039

score 116

AWS S3での画像アップロードとダウンロード

teratailのプロフィール画像のような機能を実装しようとしています。
画像ファイルをAWS S3に保存して画像のpathをDBへ保存するといった形です。

ASWのファイルに対し、User情報であるuser_idを含ませて画像をアップロード
→画像のpathをDBに保存
→pathより画像をダウンロードして画面に表示
というような機能を作りたいです。

単純にファイルのアップロード、ダウンロードの機能に関しては下のコードで
できるようになりました。サンプルのため取得する画像は"sample.jpg"で指定。

この場合ユーザー情報(int userId)を加えてuploadする場合は
object keyはどのように指定するのが適切なのでしょうか?

Controller

//アップロードしている画像ファイルsample.jpgを取得し、データをレスポンス
    @GetMapping(value = "/image",
            headers = "Accept=image/jpeg, image/jpg, image/png, image/gif",
            produces = {MediaType.IMAGE_JPEG_VALUE, MediaType.IMAGE_PNG_VALUE, MediaType.IMAGE_GIF_VALUE})
    @ResponseBody
    public ResponseEntity<BufferedImage> getImage(){
        return ResponseEntity.ok().body(
                s3DownloadHelper.getImage("sample.jpg"));
    }


    //プロフィール画像をアップロード
    @PostMapping("upload")
    public String upload(UserEditForm fileUploadModel){
        s3UploadHelper.saveFile(fileUploadModel.getUploadFile());
        return "redirect:profile/edit";
    }

uploadHelper

@Component
public class S3UploadHelper{

    private static final String S3_BUCKET_PREFIX = "s3://";
    private static final String DIRECTORY_DELIMITER = "/";

    @Value("backet")
    private String bucketName;

    @Autowired
    ResourceLoader resourceLoader;

    @Autowired
    ResourcePatternResolver resourcePatternResolver;

    @Autowired
    AmazonS3 amazonS3;



    public String saveFile(MultipartFile multipartFile){
        String objectKey = new StringBuilder()
                .append(S3_BUCKET_PREFIX)
                .append(bucketName)
                .append(DIRECTORY_DELIMITER)
                .append(multipartFile.getOriginalFilename())
                .toString();
        WritableResource writableResource = (WritableResource)resourceLoader.getResource(objectKey);
        try(InputStream inputStream = multipartFile.getInputStream();
            OutputStream outputStream = writableResource.getOutputStream()){
            IOUtils.copy(inputStream, outputStream);
        }catch (IOException e){
            e.printStackTrace();
        }
        return objectKey;
    }

}

downloadHelper

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;

import javax.imageio.ImageIO;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;

@Component
public class S3DownloadHelper{

    private static final String S3_BUCKET_PREFIX = "s3://";
    private static final String DIRECTORY_DELIMITER = "/";

    @Value("backet")
    private String bucketName;

    @Autowired
    ResourceLoader resourceLoader;

    public BufferedImage getImage(String imageFilePath){
        Resource resource = resourceLoader.getResource(
                new StringBuilder()
                .append(S3_BUCKET_PREFIX)
                .append(bucketName)
                .append(DIRECTORY_DELIMITER)
                .append(imageFilePath)
                .toString());
        BufferedImage image = null;
        //InputStreamで読み込み
        try(InputStream inputStream = resource.getInputStream()){
            image = ImageIO.read(inputStream);
        }catch (IOException e){
            e.printStackTrace();
        }
        return image;
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

 String objectKey = new StringBuilder()
                .append(S3_BUCKET_PREFIX)
                .append(bucketName)
                .append(DIRECTORY_DELIMITER)
                .append(userId)
                .toString();


と修正しユーザー情報を加えて画像を保存し、
ダウンロードもできるようになりました。
拡張子を加えずに画像を保存したらまずいと思っていたけどそんなこともなかった。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.09%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る