S3-2021.12.13
1.簡易ストレージサービスとは?
1-1. しゅとくせい
多くのユーザーがオンラインになっても、システム的な仕事をしないで引き受けることができます.
(アマゾンインフラストラクチャエージェント)
保存できるファイル数の制限はありません.
最大5 TBのデータ(少なくとも1バイト)を格納および維持できます.
ファイルを認証して、無断アクセスを防ぐことができます.
HTTPとBitTorrentプロトコルをサポートします.
REST、SOAPインタフェースを提供します.
複数の施設でデータを繰り返し保存し、データが失われたときに自動的にデータをリカバリします.
(HDDを保存するよりも安全)
バージョン管理機能により、ユーザーエラーも復元できます.
情報の重要性に応じて保護レベルを区分し、コストを削減できます.(RSS)
1-2. 主な概念
オブジェクト(object):AWSは、S 3に格納されている各データをオブジェクトと命名し、1つのファイルとして扱うだけでよい.
bucket(bucket):オブジェクトがファイルである場合、bucketは関連オブジェクトをグループ化する上位ディレクトリであってもよい.
パケット単位で領域(region)を指定したり、パケット内のすべてのオブジェクトに対して統一的な認証と接続制限を行ったりすることができます.
バージョン管理:S 3に記憶されたオブジェクトの変化を保存する.
たとえば、ユーザがAというオブジェクトを削除または変更した場合、各オブジェクトのすべての変更が記録され、エラーを挽回できます.
BitTorrent:分散ファイル配布システムとして定義できます.
ここでは、分散は1台のサーバでファイルを配布するのではなく、ファイルを所有するコンピュータからファイルをダウンロードし、一緒に貼り付けて完全なファイルを作成します.
大規模なファイルの導入にBitTorrentを使用すると、コストを大幅に削減できます.
冗長記憶装置:従来のS 3オブジェクトに比べて、データ損失の可能性が高い.
しかし、安価なため、島状画像などの復元可能なデータを格納するのに適している.
それでも、アマゾンはセキュリティが物理ハードディスクの400倍だと主張しています.
Glacier:アマゾンのストレージサービスで、極めて低い価格でデータを保存し、英語は氷河です.
2.SpringBoot AWS 3の写真をアップロードする
2-1. AWS 3 Bucketの作成
2-2. AWS 3 Bucket権限の設定
- principal:
- Actions: GetObject, PutObject
-ARN:コピーされたARN+/入力(パケット->プロパティタブ->コピーARNをクリック)
-Add Statement->OK->ポリシーの生成->コピーと貼付けをクリックします
2-3. IAMユーザー権限の追加
2-4. Spring Bootにファイルをアップロードする
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.0.1.RELEASE'
上記の形式で独自のIAMキー、パケット名、バージョンなどを入力します.
cloud:
aws:
credentials:
accessKey: IAM 사용자 엑세스 키
secretKey: IAM 사용자 비밀 엑세스 키
s3:
bucket: 버킷 이름
region:
static: ap-northeast-2
stack:
auto: false
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
@SpringBootApplication
public class ImageApplication {
public static final String APPLICATION_LOCATIONS = "spring.config.location="
+ "classpath:application.yml,"
+ "classpath:aws.yml";
public static void main(String[] args) {
new SpringApplicationBuilder(ImageApplication.class)
.properties(APPLICATION_LOCATIONS)
.run(args);
}
}
作成aws.ymlファイルで作成した値を取得し、AmazonS 3 Clientオブジェクトを作成してbeanに注入します.
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AmazonS3Config {
@Value("${cloud.aws.credentials.access-key}")
private String accessKey;
@Value("${cloud.aws.credentials.secret-key}")
private String secretKey;
@Value("${cloud.aws.region.static}")
private String region;
@Bean
public AmazonS3Client amazonS3Client() {
BasicAWSCredentials awsCreds = new BasicAWSCredentials(accessKey, secretKey);
return (AmazonS3Client) AmazonS3ClientBuilder.standard()
.withRegion(region)
.withCredentials(new AWSStaticCredentialsProvider(awsCreds))
.build();
}
}
作成=>つまり、プロジェクトルートの下でアップロードした写真ファイルを生成します.
その後、removeNewFileでローカルファイルを削除します.
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.PutObjectRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Optional;
import java.util.UUID;
@Slf4j
@RequiredArgsConstructor
@Component
public class S3Uploader {
private final AmazonS3Client amazonS3Client;
@Value("${cloud.aws.s3.bucket}")
public String bucket; // S3 버킷 이름
public String upload(MultipartFile multipartFile, String dirName) throws IOException {
File uploadFile = convert(multipartFile) // 파일 변환할 수 없으면 에러
.orElseThrow(() -> new IllegalArgumentException("error: MultipartFile -> File convert fail"));
return upload(uploadFile, dirName);
}
// S3로 파일 업로드하기
private String upload(File uploadFile, String dirName) {
String fileName = dirName + "/" + UUID.randomUUID() + uploadFile.getName(); // S3에 저장된 파일 이름
String uploadImageUrl = putS3(uploadFile, fileName); // s3로 업로드
removeNewFile(uploadFile);
return uploadImageUrl;
}
// S3로 업로드
private String putS3(File uploadFile, String fileName) {
amazonS3Client.putObject(new PutObjectRequest(bucket, fileName, uploadFile).withCannedAcl(CannedAccessControlList.PublicRead));
return amazonS3Client.getUrl(bucket, fileName).toString();
}
// 로컬에 저장된 이미지 지우기
private void removeNewFile(File targetFile) {
if (targetFile.delete()) {
log.info("File delete success");
return;
}
log.info("File delete fail");
}
// 로컬에 파일 업로드 하기
private Optional<File> convert(MultipartFile file) throws IOException {
File convertFile = new File(System.getProperty("user.dir") + "/" + file.getOriginalFilename());
if (convertFile.createNewFile()) { // 바로 위에서 지정한 경로에 File이 생성됨 (경로가 잘못되었다면 생성 불가능)
try (FileOutputStream fos = new FileOutputStream(convertFile)) { // FileOutputStream 데이터를 파일에 바이트 스트림으로 저장하기 위함
fos.write(file.getBytes());
}
return Optional.of(convertFile);
}
return Optional.empty();
}
}
作成@RequiredArgsConstructor
@RestController
public class HelloController {
private final S3Uploader s3Uploader;
@PostMapping("/images")
public String upload(@RequestParam("images") MultipartFile multipartFile) throws IOException {
s3Uploader.upload(multipartFile, "static"); // 두 번째 매개변수의 이름에 따라 S3 Bucket 내부에 해당 이름의 디렉토리가 생성
return "test";
}
}
PostManテスト
検査S 3
3.実施時の注意事項
@RequiredArgsConstructor
@RestController
public class BoardController {
private final BoardService boardService;
@PostMapping("/api/boards")
public BoardResponseDto BoardUpload(
// @AuthenticationPrincipal UserDetailsImpl userDetails,
@RequestPart(value = "multipartFile", required = false) MultipartFile multipartFile,
@RequestPart(value = "data") BoardRequestDto boardRequestDto
) throws IOException {
// return boardService.saveBoard(userDetails.getUser(), multipartFile, boardRequestDto);
return boardService.saveBoard(multipartFile, boardRequestDto);
}
}
@RequiredArgsConstructor
@Service
public class BoardService {
private final BoardRepository boardRepository;
private final S3Uploader s3Uploader;
private final String imageDirName = "static"; // S3 폴더 경로
@Transactional
// public BoardResponseDto saveBoard(User user, MultipartFile multipartFile, BoardRequestDto boardRequestDto) {
public BoardResponseDto saveBoard(
MultipartFile multipartFile,
BoardRequestDto boardRequestDto
) throws IOException {
String imgUrl = "";
if(multipartFile.getSize() != 0) { // 이미지 첨부 있으면 S3 파일 업로드
imgUrl = s3Uploader.upload(multipartFile, imageDirName);
}
Board board = Board.builder()
.title(boardRequestDto.getTitle())
.content(boardRequestDto.getContent())
// .nickname(user.getNickname())
.img(imgUrl)
.build();
boardRepository.save(board);
return BoardResponseDto.builder()
.board_id(board.getBoard_id())
.title(board.getTitle())
.content(board.getContent())
// .nickname(board.getUser().getNickname())
.img(board.getImg())
.build();
}
}
-添付ファイル
Reference
この問題について(S3-2021.12.13), 我々は、より多くの情報をここで見つけました https://velog.io/@bellpro/S3-2021.12.13テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol