Search

41. 스프링부트 포토그램 프로필 페이지 Image 서버에 업로드하기

프로필 페이지

이미지 업로드하는 컨트롤러를 완성할거다
ImageController에 imageUpload함수를 만들어주는데
@PostMapping("/image") public String imageUpload() { }
Java
복사
Image.java에 있는 caption도 받고 파일(postImageUrl를 받는게 아니라)을 받을거다
요청을 위한 dto를 만들거다.
dto 폴더 안에 image 폴더 생성 후 ImageUploadDto.java 생성
package com.cos.photogramstart.web.dto.image; import org.springframework.web.multipart.MultipartFile; import lombok.Data; @Data public class ImageUploadDto { private MultipartFile file; private String caption; }
Java
복사
ImageController.java
업로드 성공하고 나서 유저의 프로필 화면으로 넘어가게 할거다
@PostMapping("/image") public String imageUpload(ImageUploadDto imageUploadDto, @AuthenticationPrincipal PrincipalDetails principalDetails) { //서비스호출 return "redirect:/user/" + principalDetails.getUser().getId(); }
Java
복사
service 폴더 안에 ImageService.java 생성
package com.cos.photogramstart.service; import org.springframework.stereotype.Service; import com.cos.photogramstart.config.auth.PrincipalDetails; import com.cos.photogramstart.domain.image.ImageRepository; import com.cos.photogramstart.web.dto.image.ImageUploadDto; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @Service public class ImageService { private final ImageRepository imageRepository; public void 사진업로드(ImageUploadDto imageUploadDto, PrincipalDetails principalDetails) { } }
Java
복사
만들어주고 ImageController.java 에서 서비스를 호출할려면
서비스 선언 후 @RequiredArgsConstructor 달아주자.
package com.cos.photogramstart.web; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import com.cos.photogramstart.config.auth.PrincipalDetails; import com.cos.photogramstart.service.ImageService; import com.cos.photogramstart.web.dto.image.ImageUploadDto; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @Controller public class ImageController { private final ImageService imageService; @GetMapping({"/","/image/story"}) public String story() { return "image/story"; } @GetMapping("/image/popular") public String popular() { return "image/popular"; } @GetMapping("/image/upload") public String upload() { return "image/upload"; } @PostMapping("/image") public String imageUpload(ImageUploadDto imageUploadDto, @AuthenticationPrincipal PrincipalDetails principalDetails) { //서비스호출 imageService.사진업로드(imageUploadDto, principalDetails); return "redirect:/user/" + principalDetails.getUser().getId(); } }
Java
복사
이렇게 컨트롤러로 만들고 이제 서비스에서 다 구현해주면 된다
ImageService에서 실제 파일의 이름을 받아준다
public void 사진업로드(ImageUploadDto imageUploadDto, PrincipalDetails principalDetails) { String imageFileName = imageUploadDto.getFile().getOriginalFilename(); [//1.jpg](notion://1.jpg/) }
Java
복사
서버 안에 upload 라는 폴더 안에 1.jpg가 저장되고 DB에는 파일위치의 경로(/upload/1.jpg)가 저장된다.
근데 다른 사진의 이미지이지만 파일명이 1.jpg로 들어오면 사진이 덮어 씌어 질거다.
그래서 구분 하기 위해 필요한게 UUID(네트워크 상에서 고유성이 보장되는 ID를 만들기 위한 표준 규약)다
public void 사진업로드(ImageUploadDto imageUploadDto, PrincipalDetails principalDetails) { UUID uuid = UUID.randomUUID(); //uuid String imageFileName = imageUploadDto.getFile().getOriginalFilename(); //1.jpg }
Java
복사
근데 진짜 거의없겠지만 혹시 모를 극악의 확률로 같은 UUID가 생성될 수 도 있어서
imageFileName 앞에 UUID를 붙여줄거다.
String imageFileName = uuid + "_"+ imageUploadDto.getFile().getOriginalFilename(); //1.jpg
Java
복사
Path imageFilePath = Paths.get(null)
Java
복사
.get()에 실제 저장한 파일 경로를 넣어줘야하는데
application.yml에 파일위치를 저장한 경로를 이렇게 써주면된다
file: path: C:/workspace/springbootwork/upload/
Java
복사
맥인 경우는 같은 프로젝트안 폴더에 생성
file: path: /Users/유저명/git/photogram_sns_springboot_/photogram/upload/
Java
복사
servlet: multipart: enabled: true max-file-size: 2MB
Java
복사
enabled: true를 두면서 사진을 받겠다 근데 최대 사이즈는 2MB 로 설정
ImageController.java에서 application.yml에 잡은 경로를 갖고온다
@Value("${file.path}") private String uploadFolder;
Java
복사
@Value 사용해서 넣어주면 path로 잡은 경로를 갖고온다.
Path imageFilePath = Paths.get(uploadFolder + imageFileName); //통신, I/O(하드디스크 기록하거나 읽을때) -> 예외가 발생할 수 있다. -> 예외처리해줘야한다. try { //path 실제이미지파일 +바이트화 Files.write(imageFilePath, imageUploadDto.getFile().getBytes()); } catch (Exception e) { e.printStackTrace(); }
Java
복사
예외처리 및 파일 저장까지 처리해준다
upload.jsp에서 form 태그 안에 action을 잡아준다
enctype="application/x-www-form-urlencoded"
Java
복사
라고 기본적으로 key=value 타입으로 잡아주는게 있는데 우리는 지금 파일도 보내주고 key=value값도 보내주고싶다. 그래서
enctype="multipart/form-data"
Java
복사
으로 설정하면 적용된다
이제 사진이 업로드 되는지 테스트해본다
업로드 성공시
메인 프로필 화면으로 리다이렉트 된걸볼 수 있다.
사진업로드 함수에 찍은 이미지 파일이름도 콘솔에 잘 찍힘.
이제 데이터베이스에 사진경로만 넣어주면 끝난다

*참고