일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- 스프링부트중복예외처리
- springboot_exception_handler
- 도커설치하는법
- vm도커설치하는법
- 출처 따배도
- 서버에도커설치
- 파이썬sort
- 스프링이미지업로드
- 인스타클론
- 스프링부트사진올리기
- 스프링부트
- 스프링구독
- 스프링부트팔로우취소
- 출처 노마드코더
- 스프링사진
- 스프링익셉션처리
- 스프링부트api
- 우분투도커설치
- 출처 문어박사
- WAS웹서버
- 스프링부트서버에사진전송
- 스프링부트구독취소
- 출처 코딩셰프
- dockerinstall
- 스프링부트팔로잉
- 출처 메타코딩
- centos도커설치
- 스프링사진업로드
- ssh도커설치
- 멀티폼
- Today
- Total
MakerHyeon
[springBoot] 프로필 페이지 -Image모델 만들기/서버에 업로드하기 본문
프로필 페이지 -Image모델 만들기/서버에 업로드하기
● Image모델 만들기
1. Image table 생성
- 사진을 전송받아서 그 사진을 서버의 특정폴더에 저장후, DB에 저장된 경로를 insert
- 유저 : 이미지 = 1: N, 이미지 : 유저 = N : 1 (@ManyToOne)
- 오브젝트는 FK로 저장된다. 따라서 JoinColumn명을 지정해준다.
// Image.java
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class Image {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String caption;
private String postImageUrl;
@JoinColumn(name="userId")
@ManyToOne
private User user;
// 이미지 좋아요,댓글도 추후 만들예정!
private LocalDateTime createDate;
@PrePersist
public void createDate(){
this.createDate = LocalDateTime.now();
}
}
2.해당 table Repository만들기
// ImageRepository.java
public interface ImageRepository extends JpaRepository<Image,Integer> {
}
● Image Upload to Server
3. Image Upload DTO생성
- upload.jsp의 name="file", name="caption" 데이터를 받기위한 Dto생성
// ImageUploadDto.java
@Data
public class ImageUploadDto {
private MultipartFile file;
private String caption;
}
4. imageController 파라미터 설정
- 컨트롤러는 사용자에게 데이터를 받고, 서비스를 호출하는 역할을 담당
// ImageController.java
...
@PostMapping("/image")
public String image(ImageUploadDto imageUploadDto,
@AuthenticationPrincipal PrincipalDetails principalDetails){
//서비스 호출
// 해당유저의 페이지로 redirection
return "redirect:/user/"+principalDetails.getUser().getId();
}
5. application.yml에서 file path 경로 설정
- file path를 지정할때 맨 뒤에 \ 를 붙여주어야 함에 유의
- 유지보수성을 위해, yml에 경로를 적어두고 @Value로 Path 불러와 적용하는게 좋다.
// application.yml
file:
path: C:\Users\USER\Desktop\metacoding\upload\
6. ImageService 에서 사진업로드함수 구현부 작성
- @Value로 Path값 지정 (private String uploadFolder = "C:\Users\USER\Desktop\metacoding\")
- 통신 I/O 는 예외가 발생할 수 있기 때문에 예외처리(try-catch) 를 해준다.
- 이미지 중복 방지를 위해 UUID를 사용한다.
-UUID란(Universally Unique IDentifier), 네트워크 상에서 고유성이 보장되는 id를 만들기 위한 표준 규약으로, 중복이없고 유일성이 보장되는 코드
// ImageService.java
@RequiredArgsConstructor
@Service
public class ImageService {
private final ImageRepository imageRepository;
@Value("${file.path}")
private String uploadFolder;
public void 사진업로드(ImageUploadDto imageUploadDto, PrincipalDetails principalDetails){
UUID uuid = UUID.randomUUID(); //uuid
String imageFileName = uuid + "_" + imageUploadDto.getFile().getOriginalFilename();
System.out.println("이미지 파일이름: "+imageFileName);
Path imageFilePath = Paths.get(uploadFolder + imageFileName);
try{
Files.write(imageFilePath,imageUploadDto.getFile().getBytes());
} catch (Exception e){
e.printStackTrace();
}
}
}
7. imageController 에서 업로드서비스 호출
// ImageController.java
@RequiredArgsConstructor
@Controller
public class ImageController {
private final ImageService imageService;
...
@PostMapping("/image")
public String image(ImageUploadDto imageUploadDto,
@AuthenticationPrincipal PrincipalDetails principalDetails){
// 서비스 호출
imageService.사진업로드(imageUploadDto,principalDetails);
return "redirect:/user/"+principalDetails.getUser().getId();
}
}
8. form에서 event action 지정
- enctype="multipart/form-data" : 여러가지 종류의 데이터를 묶어서 전송할때 쓰는 타입
- image file과 key=value 데이터를 동시에 전송하기 위함
// upload.jsp
<form class="upload-form" action="/image" method="post" enctype="multipart/form-data">
<input type="file" name="file" onchange="imageChoose(this)"/>
<div class="upload-img">
<img src="/images/person.jpeg" alt="" id="imageUploadPreview" />
</div>
<!--사진설명 + 업로드버튼-->
<div class="upload-form-detail">
<input type="text" placeholder="사진설명" name="caption"/>
<button class="cta blue">업로드</button>
</div>
● 결과
- 이미지 업로드가 정상적으로 완료된것을 확인 가능 하다.
● upload폴더를 프로젝트 외부에 두는 이유 ?
- 서버가 실행되면 .java파일들이 전부 컴파일되어서 타켓폴더안에 들어가게되고 (.class),이를 실행하게 된다.
만약에 업로드 폴더를 프로젝트 내부에 만들게되면,이것이 실행시 Target에 반영이 된다.
- Target파일로 .class, 정적파일을 집어넣는 행위를 deploy라고 한다.
- deploy(배포)될때 시간이 걸린다. 이때문에 이미지가 타겟안으로 들어가기도 전에 서버가 실행될 수 있다. Deploy되는 시간보다 화면으로 돌아가는 시간이 더 빠르다면, 시간차 문제로 엑박이 뜨게된다.
- 프로젝트 외부에 업로드폴더를 두면 Deploy될 필요가없다. 찾을때도 target에 있는걸 찾는 게아니라 upload폴더에 있는것을 찾는다.
- 즉 정리하면,위같은 이유로 파일은 프로젝트 내부에 두지않아야한다.
*정리
1.프로젝트 내부에 있으면 [업로드->프로젝트 내부->deploy]되는 시간보다 프로필페이지로 가는 시간이 더 빠를 수 있다.
2.프로젝트 외부에두면 deploy가 안되기때문에 업로드하자마자 프로필페이지로 가도 엑박이 안뜬다!
'SpringBoot' 카테고리의 다른 글
[springBoot] 프로필 페이지 -유효성검사 (0) | 2023.01.09 |
---|---|
[springBoot] 프로필 페이지 -Image를 DB에 업로드 (0) | 2023.01.09 |
[springBoot] 구독하기 -연관관계와 모델만들기 (0) | 2023.01.08 |
[springBoot] 회원정보수정(Ajax,유효성검사) (0) | 2023.01.06 |
[springBoot] Security Tag library (0) | 2023.01.05 |