간단한 게시판을 만드던 중 이미지 업로드하는 기능이 필요해서 만들어보았다.
1. 이미지 이름
이미지를 보내서 저장할 때는 이미지의 이름이 중요하다.
같은 이름을 가진 이미지를 전송할 경우 충돌이 일어나기 때문이다.
그래서 같은 이름을 가지더라도 서로 구분할 수 있도록 문자열을 붙여준다.
private static String changedImageName(String originName) {
String random = UUID.randomUUID().toString();
return random+originName;
}
2. 이미지 클래스
@AllArgsConstructor
@Getter
public class Image {
//요청을 하면 클라이언트에게 originName을 보여주고
//storedImagePath에 저장된 경로에서 불러오면 됨
private String originName;
private String storedImagePath;
}
위에서 새로운 이미지 이름을 생성했다.
그래도 원래의 이미지 이름이 필요할 수 있으므로 새로 만든 이미지 이름과 같이 보관을 하기 위해서 Image 클래스를 생성했다.
2. 저장될 이미지의 경로
private static String createDirPath(String changedName) {
return "c:\\images\\"+changedName;
//이미지가 저장될 경로. 필요에 따라 경로 조정
}
3. 이미지 업로드
public static Image uploadImage(MultipartFile image) {
String originName = image.getOriginalFilename();
String changedName = changedImageName(originName);
String storedImagePath = createDirPath(changedName);
System.out.println("storedImagePath = " + storedImagePath);
try {
image.transferTo(new File(storedImagePath));
} catch (IOException e){
throw new ImageUploadException();
//내가 만든 커스텀 예외.
//직접 만든 예외라서 적절히 변경하여 사용.
}
return new Image(originName, storedImagePath);
}
이미지는 MultipartFile 타입으로 받게 되는데 이 타입의 getOriginalFilename 메소드를 사용하여 원래 이미지 이름을 얻을 수 있다.
이를 사용하여 새롭게 이름을 만들고 경로를 만든다.
그리고 이미지를 저장하기 위해서 MultipartFile의 transferTo 메소드를 사용한다.
인자로 넣어둔 경로로 이미지가 저장된다.
또한 예외가 발생하면 커스텀 예외를 던져준다. 이는 @RestControllerAdvice 어노테이션이 달린 곳에서 처리하도록 하였다.
(@RestControllerAdvice 참고)
https://growth-coder.tistory.com/101
깃헙 참고 : https://github.com/ezcolin2/Spring-Class/tree/main/image%20upload
JSON 파일과 함께 이미지 파일 받기
이미지 파일만 받는다면 보통 @RequestParam 어노테이션을 사용해서 받는다.
그런데 나는 게시글을 올릴 때 게시글의 정보와 함께 이미지를 넘겨주고 싶었다.
이럴 때는 @RequestPart 어노테이션을 사용한다.
먼저 @RequestPartm 어노테이션을 사용한 컨트롤러의 모습은 아래와 같다.
@PostMapping("")
public ResponseEntity<JsonResponse> registerPost(
@RequestPart(value="post", required = true) PostDto post,
@RequestPart(value="image", required = true) MultipartFile image
) {
postService.registerPost(post, image);
JsonResponse response = JsonResponse.builder()
.code(HttpStatus.OK.value())
.httpStatus(HttpStatus.OK)
.message("게시글 등록 성공").build();
return new ResponseEntity<>(response, response.getHttpStatus());
}
@RequestPartm 두번째 인자로 required=true가 들어가있는데 이는 default 값이라서 굳이 안적어도 된다.
나는 이미지를 반드시 첨부해야 글이 등록되도록 만들 예정이라 true로 두었는데 그렇지 않아도 된다면 false로 두고 따로 null 처리를 해줘야한다.
@RequestParam을 활용한 형태는 form-data 형태로 넘겨줘야한다.
postman 기준으로 key-value 쌍으로 넘겨주게된다.
post라는 key에 해당하는 VALUE는 길어서 생략되었는데 아래와 같다.
{
"postTitle" : "테스트 제목",
"writerId" : "테스트 유저",
"time" : "2022-01-25",
"content" : "안녕하세요 신입입니다."
}
이러한 JSON 형식은 꼭 content type에 application/json을 적어줘야한다.
그리고 포스트맨은 기본적으로 text로 설정되어있는데 파일을 넣고 싶으면 위 사진처럼 Text에서 File로 변경해야한다.
기본적인 이미지 업로드 방식에 대해 알고싶어서 정말 간단하게 구현해보았다.
부족한 점이 많이 보이지 프로젝트를 조금 더 진행하면서 보완해나갈 예정이다.
'공부 > Spring' 카테고리의 다른 글
[Spring][JPA] H2 데이터베이스를 사용한 JPA 기초 사용법 (0) | 2023.02.10 |
---|---|
[Spring][스프링 MVC 1편] 서블릿 기초 사용법 (0) | 2023.02.08 |
[Spring][Lombok] @Data 어노테이션의 분석 (equals, hashCode) (0) | 2023.02.04 |
[Spring] Custom error 만들어서 공통 에러 처리하기 (0) | 2023.02.02 |
[Spring] 로그인, 회원 가입 결과 반환 형식 (0) | 2023.01.30 |
댓글