IT/Spring

File Upload

iamhyeon 2024. 11. 21. 02:24

코드 분석
회원관리 - 회원가입부분  파일업로드
 
🫛 RestController
 
🫛 업로드 받기  

UploadItem uploadItem = null;
uploadItem = fileHelper.saveMultipartFile(photo);

 
 
>>> FileHelper 🗂️
 
🗂️ 파일의 원본 이름 추출

String originName = multipartFile.getOriginalFilename();

ex)  originName = imgname.png
 
🗂️ 업로드 된 파일이 저장될 폴더의 이름을 "년/월/일" 형식으로 생성  

Calendar c = Calendar.getInstance();
String targetDir = String.format("%s/%04d/%02d/%02d", uploadDir, c.get(Calendar.YEAR), c.get(Calendar.MONTH)+1, c.get(Calendar.DAY_OF_MONTH) );
File f = new File(targetDir);
if (!f.exists()) {
	f.mkdirs();
}

ex)  upload.dir = /C:/HYEON_GitHub/upload
ex)  targetDir = /C:/HYEON_GitHub/upload/2024/11/21
 
🗂️ 저장될 파일의 이름을 생성한다

// 파일의 원본 이름에서 확장자만 추출
String ext = originName.substring(originName.lastIndexOf("."));
String fileName = null; // 웹 서버에 저장될 파일이름
File targetFile = null; // 저장된 파일 정보를 담기 위한 File 객체
int count = 0; // 중복된 파일  수

// 일단 무한루프
while(true) {
    // 저장될 파일 이름 => 현재시각 + 카운트값 + 확장자
    fileName = String.format( "%d%d%s", System.currentTimeMillis(), count, ext );
    // 업로드 파일이 저장될 폴더 + 파일이름으로 파일객체 생성
    targetFile = new File(targetDir, fileName);

    // 동일한 이름의 파일이 없다면 반복 중단
    if (!targetFile.exists()) {
        break;
    }
    // if문을 빠져나올 경우 중복된 이름의 파일이 존재한다는 의미이므로 count 1증가
    count++;
}

ex)  targetDir = /C:/HYEON_GitHub/upload/2024/11/21
ex)  fileName = 17321211783290.png
ex)  targetFile = C:\HYEON_GitHub\upload\2024\11\21\17321211783290.png    (targetDir + fileName)
 
🗂️ 파일 업로드 수행

// 업로드 된 파일을 지정된 경로로 복사한다
try {
    multipartFile.transferTo(targetFile);
} catch (Exception e) {
    log.error("업로드된 파일을 저장하는 중에 문제가 발생했습니다", e);
    throw e;
}

multipartFile.transferTo(uploadPath);
: transferTo 메서드는 MultipartFile에서 제공하는 메서드 중에 하나로, 업로드된 파일을 지정된 경로에 저장하는 역할을 한다. 이 메서드를 사용하여 업로드된 파일을 서버의 특정 경로로 옮기거나 저장할 수 있다. 이 메서드는 IOExeption을 던질 수 있으므로 이를 처리하는 예외 처리 로직을 추가하는 것이 좋다.
ex)  C:\HYEON_GitHub\upload\2024\11\21\17321211783290.png       targetFile경로에 저장
 
🗂️ 업로드 경로 정보 처리하기

// 복사된 파일의 절대경로를 추출한다
// => 운영체제 호환 (Windows => Linux) 을 위해 역슬래시를 슬래시로 변환한다
String absPath = targetFile.getAbsolutePath().replace("\\", "/");

ex)  absPath = C:/HYEON_GitHub/upload/2024/11/21/17321211783290.png

// 업로드 된 파일의 절대경로(absPath)에서 환경설정 파일에 명시된 폴더까지의 위치는 삭제하여 
// 환경설정 파일에 명시된 upload.dir 이후의 위치만 추출한다 (윈도우만)
String filePath = null;
if (absPath.substring(0,1).equals("/")) {
	filePath = absPath.replace(uploadDir, "");
} else {
    // Windows용 경로처리 => 설정 파일에 명시한 첫 글자(/)를 제거해야 한다
    filePath = absPath.replace(uploadDir.substring(1), "");
}

ex)  absPath = C:/HYEON_GitHub/upload/2024/11/21/17321211783290.png
ex)  upload.dir = /C:/HYEON_GitHub/upload
ex)  filePath = /2024/11/21/17321211783290.png

// 업로드 경로를 웹 상에서 접근 가능한 경로 문자열로 변환하여  Beans에 추가한다
String fileUrl = String.format("%s%s", uploadUrl, filePath);

ex)  fileUrl = /files/2024/11/21/17321211783290.png

 
🗂️ 업로드 결과를 Beans에 저장

UploadItem item = new UploadItem();
item.setContentType(multipartFile.getContentType());
item.setFieldName(multipartFile.getName());
item.setFileSize(multipartFile.getSize());
item.setOriginName(originName);
item.setFilePath(filePath);
item.setFileUrl(fileUrl);

▽ log

[DEBUG] 24-11-21 01:46:18 [FileHelper:291] - 
UploadItem(
fieldName=photo, 
originName=spiderman.png, 
contentType=image/png, 
fileSize=48983, 
filePath=/2024/11/21/17321211783290.png, 
fileUrl=/files/2024/11/21/17321211783290.png, 
thumbnailPath=/2024/11/21/17321211783290_120x120.png, 
thumbnailUrl=/files/2024/11/21/17321211783290_120x120.png)

 
🗂️ 파일 유형이 이미지라면 썸네일 생성
 
 
🫛 정보를 Service에 전달하기 위한 객체 구성

Member member = new Member();
member.setUserId(userId);
member.setUserPw(userPw);
member.setUserName(userName);
member.setEmail(email);
member.setPhone(phone);
member.setBirthday(birthday);
member.setGender(gender);
member.setPostcode(postcode);
member.setAddr1(addr1);
member.setAddr2(addr2);

if (uploadItem != null) {
    member.setPhoto(uploadItem.getFilePath());    
}

try {
    memberService.addItem(member);
} catch (Exception e) {
    return restHelper.serverError(e);
}

return restHelper.sendJson();

ex)  filePath = /2024/11/21/17321211783290.png


▽ log 회원가입

[DEBUG] 24-11-21 01:46:18 [insert:135] - ==> Parameters: 
dddd(String), qwe123(String), 디디디(String), d@d.com(String), 01033335555(String), 
2024-11-13(String), M(String), 03992(String), 서울 마포구 동교로 171 (동교동)(String), 201(String), 
/2024/11/21/17321211783290.png(String)
[INFO ] 24-11-21 01:46:29 [MyInterceptor:80] - [GET] 
http://localhost/files/2024/11/21/17321211783290.png

▽ log 이미지 변경

[DEBUG] 24-11-21 01:46:47 [FileHelper:328] - [Thumbnail] saveFile: 
C:\HYEON_GitHub\upload\2024\11\21\17321212071520_120x120.png
[DEBUG] 24-11-21 01:46:47 [FileHelper:291] - 
UploadItem(fieldName=photo, originName=unnamed.png, contentType=image/png, fileSize=4188, 
filePath=/2024/11/21/17321212071520.png, 
fileUrl=/files/2024/11/21/17321212071520.png, 
thumbnailPath=/2024/11/21/17321212071520_120x120.png, 
thumbnailUrl=/files/2024/11/21/17321212071520_120x120.png)
[DEBUG] 24-11-21 01:46:47 [update:135] - ==> Parameters: 
디디디(String), d@d.com(String), 01033335555(String), 2024-11-13(String), M(String), 
03992(String), 서울 마포구 동교로 171 (동교동)(String), 201(String), 
/2024/11/21/17321212071520.png(String), 17(Integer), qwe123(String)

 
 
 
 
 


refer to
https://velog.io/@dani0817/Spring-%ED%8C%8C%EC%9D%BC%EC%97%85%EB%A1%9C%EB%93%9CMultipartFile

반응형

'IT > Spring' 카테고리의 다른 글

MyBatisSystemException  (0) 2024.11.25
Spring 파일 업로드 경로 맵핑  (0) 2024.11.21
Interceptor  (0) 2024.10.23
Spring 프로젝트 구성  (0) 2024.10.16
Spring 프로젝트 생성하기  (2) 2024.10.15