intellij object를 변환할 땐 DTO, 페이지 나누기 (pagination), 이미지 업로드 기능 1 (S3 셋팅), 이미지 업로드 기능 2 (Presigned URL), AWS Elastic Beanstalk에 Spring boot 서버 배포
object를 변환할 땐 DTO
*object안의 내용을 다른 형식으로 변환해야 할때, DTO or Map 사용*
DTO = Data Transfer Object = 데이터 변환용 클래스
DTO 장점 = 타입체크가 쉬움, 재사용 용이,
@GetMapping("/user/1")
@ResponseBody
public MemberDto getUser(){
var a = memberRepository.findById(2L);
var result = a.get();
var data = new MemberDto(result.getUsername(), result.getDisplayName());
return data;
}
}
class MemberDto{
public String username;
public String displayName;
MemberDto(String a, String b){
this.username = a;
this.displayName = b;
}
}
페이지 나누기 (pagination)
page가져오는 함수 만들기 - ItemRepository
Page<Item> findPageBy(Pageable page);
controller - 해당 함수 불러오기 - (0, 5) = (몇번째 페이지, 페이지당 몇개)(1~5번째 글)
@GetMapping("/list/page/{page}")
String getListPage(Model model, @PathVariable Integer page){
Page<Item> result = itemRepository.findPageBy(PageRequest.of(page-1,5));
model.addAttribute("items", result);
model.addAttribute("pages", result.getTotalPages());
return "list.html";
}
<div>
<button th:each="i : ${#numbers.sequence(1, pages)}" th:text="${i}" th:attr="onclick=|location.href='/list/page/${i}'|"></button>
</div>
이미지 업로드 기능 1 (S3 셋팅)
이미지 데이터를 db에 넣기에는 용량이 너무 크다.
그래서 경로만 db에 넣고, 이미지 데이터는 S3라는 곳에 저장한다.
S3 설치 - aws.com - s3 검색 - 버킷 만들기 - 버킷 이름 작성(유니크) - 객체 소유권 비활성화
- 모든 퍼블릭 엑세스 차단 체크 끄기(활성화) - 버킷 만들기 - 만든 버킷 들어가기
- 권한(탭) - 버킷 정책의 편집 클릭 -
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::님들버킷명/*"
},
{
"Sid": "2",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::님들AWS계정ID:root"
},
"Action": [
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::님들버킷명/*"
}
]
}
위 코드 복.붙 - 님들버킷명(codingapplelee) - 님들AWS계정ID(우측 상단 계정 ID, '-' 제거)
- 변경 사항 저장 - CORS의 편집 클릭 -
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"PUT",
"POST"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [
"ETag"
]
}
]
위 코드 복.붙 - 변경 사항 저장
상단의 iam 검색 - Quick Links의 내 보안 자격 증명 클릭 - 엑세스 키 만들기 - 체크 후 엑세스 키 만들기
S3 라이브러리 설치/셋팅
build.gradle -
implementation 'io.awspring.cloud:spring-cloud-aws-starter-s3:3.1.1'
추가 - application.propertiles -
spring.cloud.aws.credentials.accessKey=님들액세스키
spring.cloud.aws.credentials.secretKey=님들시크릿키
spring.cloud.aws.s3.bucket=님들버킷명
spring.cloud.aws.region.static=ap-northeast-2
추가
*서버에 이미지 요청을 하면, Presigned URL 발급, 그 URL을 fetch문을 통해 S3에 저장*
이미지 업로드 기능 2 (Presigned URL)
1) 유저가 이미지를 고르고, 서버에게 Presigned URL 요청
2) 서버는 유저에게 Presigned URL 발급
3) 유저는 그 Presigned URL로 이미지를 넣어서 PUT요청
1 = input 태그안에 type을 file로 하고 onchage="함수(this)"를 만듦(this = 파일의 값),
파일의 값(this)을 안전하게 인코딩하여 fetch문을 통해 controller로 보냄.
<input type="file" onchange="getURL(this)">
<script>
function getURL(e){
let name = encodeURIComponent(e.files[0].name)
fetch('/presigned-url?filename=' + name)
}
</script>
2 = Presigned URL 발급하는 Service class 생성 후 작성,
"test/" + filename = 버킷 내의 test폴더 내에 filename을 저장,
Presigned URL을 result에 저장(text형태).
private final S3Service s3Service;
@GetMapping("/presigned-url")
@ResponseBody
String getURL(@RequestParam String filename){
var result = s3Service.createPresignedUrl("test/" + filename);
System.out.println(result);
return result;
}
@Service
@RequiredArgsConstructor
public class S3Service {
@Value("${spring.cloud.aws.s3.bucket}")
private String bucket;
private final S3Presigner s3Presigner;
String createPresignedUrl(String path) {
var putObjectRequest = PutObjectRequest.builder()
.bucket(bucket)
.key(path)
.build();
var preSignRequest = PutObjectPresignRequest.builder()
.signatureDuration(Duration.ofMinutes(3))
.putObjectRequest(putObjectRequest)
.build();
return s3Presigner.presignPutObject(preSignRequest).url().toString();
}
}
async function getURL(e){
let name = encodeURIComponent(e.files[0].name)
let result = await fetch('/presigned-url?filename=' + name)
result = await result.text();
console.log(result);
}
3 = fetch문으로 Presigned URL(result) 경로로 이미지를 body에 넣어서 put요청,
제대로 저장이 되었는지 aws의 s3의 버킷 들어가서 확인,
받은 이미지 경로 정보의 '?'뒤의 내용은 없애기,
성공적으로 이미지를 가져왔다면 if문을 통해 img태그에 img 부여.
<img src="">
<script>
async function getURL(e){
let name = encodeURIComponent(e.files[0].name)
let result = await fetch('/presigned-url?filename=' + name)
result = await result.text();
let 결과 = await fetch(result, {
method: 'PUT',
body: e.files[0]
})
console.log(결과.url.split("?")[0])
if (결과.ok) {
document.querySelector('img').src = 결과.url.split("?")[0]
}
}
</script>
AWS Elastic Beanstalk에 Spring boot 서버 배포
AWS Elastic Beanstalk 사용
codingapple의 자료에서 배포 방법 확인