Skip to content

Commit

Permalink
파일 기능 구현 #6 (#91)
Browse files Browse the repository at this point in the history
  • Loading branch information
nardis0321 authored Jan 17, 2025
2 parents 0d24a46 + 167d430 commit cb58be1
Show file tree
Hide file tree
Showing 24 changed files with 1,173 additions and 93 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@

import com.palbang.unsemawang.common.constants.ResponseCode;
import com.palbang.unsemawang.common.response.ErrorResponse;
import com.palbang.unsemawang.common.util.file.exception.FileDeleteException;
import com.palbang.unsemawang.common.util.file.exception.FileNotFoundException;
import com.palbang.unsemawang.common.util.file.exception.FileSizeExceededException;
import com.palbang.unsemawang.common.util.file.exception.FileUploadException;
import com.palbang.unsemawang.common.util.file.exception.InvalidFileFormatException;

import lombok.extern.slf4j.Slf4j;

Expand Down Expand Up @@ -84,4 +89,61 @@ public ResponseEntity<Map<String, Object>> handleValidationException(MethodArgum
.status(HttpStatus.BAD_REQUEST)
.body(response);
}

// 파일 관련 예외 -------------------------------------------------------------------

@ExceptionHandler(FileDeleteException.class)
public ResponseEntity<ErrorResponse> handleFileDeleteException(FileDeleteException ex) {

log.error("FileDeleteException occurred: {}", ex.getMessage());
ErrorResponse response = ErrorResponse.of(ResponseCode.ERROR_DELETE);

return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(response);
}

@ExceptionHandler(FileNotFoundException.class)
public ResponseEntity<ErrorResponse> handleFileNotFoundException(FileNotFoundException ex) {

log.error("FileNotFoundException occurred: {}", ex.getMessage());
ErrorResponse response = ErrorResponse.of(ResponseCode.ERROR_SEARCH);

return ResponseEntity
.status(HttpStatus.NOT_FOUND)
.body(response);
}

@ExceptionHandler(FileSizeExceededException.class)
public ResponseEntity<ErrorResponse> handleFileSizeExceededException(FileSizeExceededException ex) {

log.error("FileSizeExceededException occurred: {}", ex.getMessage());
ErrorResponse response = ErrorResponse.of(ResponseCode.MAX_VALUE);

return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(response);
}

@ExceptionHandler(FileUploadException.class)
public ResponseEntity<ErrorResponse> handleFileUploadException(FileUploadException ex) {

log.error("FileUploadException occurred: {}", ex.getMessage());
ErrorResponse response = ErrorResponse.of(ResponseCode.ERROR_INSERT);

return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(response);
}

@ExceptionHandler(InvalidFileFormatException.class)
public ResponseEntity<ErrorResponse> handleInvalidFileFormatException(InvalidFileFormatException ex) {

log.error("InvalidFileFormatException occurred: {}", ex.getMessage());
ErrorResponse response = ErrorResponse.of(ResponseCode.NOT_EXIST_TYPE);

return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(response);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.palbang.unsemawang.common.util.file.dto;

public enum FileReferenceType {
MEMBER_PROFILE_IMG,
COMMUNITY_BOARD
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.palbang.unsemawang.common.util.file.dto;

/**
* 해당 파일이 필요한 곳의 정보로 파일을 요청
* of 메서드 사용해주세요
* @param referenceType 참조할 테이블명_파일유형 e.g FileReferenceType.MEMBER_PROFILE_IMAGE
* @param referenceId 참조할 컬럼 ID (Long)
* @param referenceStringId 참조할 컬럼 ID (String)
*/
public record FileRequest(
FileReferenceType referenceType,
Long referenceId,
String referenceStringId
) {
public static FileRequest of(FileReferenceType referenceType, Long referenceId) {
return new FileRequest(referenceType, referenceId, null);
}

public static FileRequest of(FileReferenceType referenceType, String referenceStringId) {
return new FileRequest(referenceType, null, referenceStringId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.palbang.unsemawang.common.util.file.entity;

import java.time.LocalDate;

import com.palbang.unsemawang.common.entity.BaseEntity;
import com.palbang.unsemawang.common.util.file.dto.FileReferenceType;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class File extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String s3Key;
private String type;
private long size;

private FileReferenceType referenceType;
private Long referenceId;
private String referenceStringId;

private boolean isDeleted;
private LocalDate expireDate;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.palbang.unsemawang.common.util.file.exception;

public class FileDeleteException extends RuntimeException {

public FileDeleteException() {
}

public FileDeleteException(String message) {
super(message);
}

public FileDeleteException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.palbang.unsemawang.common.util.file.exception;

public class FileNotFoundException extends RuntimeException {

public FileNotFoundException(String message) {
super(message);
}

public FileNotFoundException() {
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.palbang.unsemawang.common.util.file.exception;

public class FileSizeExceededException extends RuntimeException {

public FileSizeExceededException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.palbang.unsemawang.common.util.file.exception;

public class FileUploadException extends RuntimeException {

public FileUploadException() {
}

public FileUploadException(String message) {
super(message);
}

public FileUploadException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.palbang.unsemawang.common.util.file.exception;

public class InvalidFileFormatException extends RuntimeException {
public InvalidFileFormatException(String message) {
super(message);
}

public InvalidFileFormatException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.palbang.unsemawang.common.util.file.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.palbang.unsemawang.common.util.file.entity.File;

@Repository
public interface FileRepository extends JpaRepository<File, Long>, FileRepositoryCustom {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.palbang.unsemawang.common.util.file.repository;

import java.util.List;

import com.palbang.unsemawang.common.util.file.dto.FileRequest;
import com.palbang.unsemawang.common.util.file.entity.File;

public interface FileRepositoryCustom {
List<File> findFilesByFileReference(FileRequest fileRequest);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.palbang.unsemawang.common.util.file.repository;

import static com.palbang.unsemawang.common.util.file.entity.QFile.*;

import java.util.List;

import org.springframework.stereotype.Repository;

import com.palbang.unsemawang.common.util.file.dto.FileRequest;
import com.palbang.unsemawang.common.util.file.entity.File;
import com.querydsl.jpa.impl.JPAQueryFactory;

import lombok.RequiredArgsConstructor;

@Repository
@RequiredArgsConstructor
public class FileRepositoryCustomImpl implements FileRepositoryCustom {

private final JPAQueryFactory queryFactory;

@Override
public List<File> findFilesByFileReference(FileRequest fileRequest) {

if (fileRequest.referenceStringId() == null) {
return queryFactory
.select(file)
.from(file)
.where(
file.referenceId.eq(fileRequest.referenceId())
.and(file.referenceType.eq(fileRequest.referenceType()))
)
.orderBy(file.id.asc())
.fetch();
} else {
return queryFactory
.select(file)
.from(file)
.where(
file.referenceStringId.eq(fileRequest.referenceStringId())
.and(file.referenceType.eq(fileRequest.referenceType()))
)
.orderBy(file.id.asc())
.fetch();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.palbang.unsemawang.common.util.file.service;

import java.util.List;

import org.springframework.web.multipart.MultipartFile;

import com.palbang.unsemawang.common.util.file.dto.FileRequest;

public interface FileService {

/**
* 이미지 업로드
* @param file 업로드 할 이미지 파일
* @param fileRequest ReferenceType과 ReferenceId 입력
*/
void uploadImage(MultipartFile file, FileRequest fileRequest);

/**
* 프로필 이미지 url 반환
* @param referenceId 참조된 회원 id, referenceId로 사용된 id
* @return 해당 회원의 프로필 이미지 or 디폴트 프로필 이미지
*/
String getProfileImgUrl(String referenceId);

/**
* 파일 url 리스트 반환
* @param fileRequest ReferenceType(참조 테이블명)과 ReferenceId(참조 id) 입력
* @return 파일 url 리스트
*/
List<String> getFileUrls(FileRequest fileRequest);

/**
* 이미지 수정 : 이미지는 반드시 하나여야 함
* @param file 수정된 파일
* @param fileRequest 수정할 위치: ReferenceType, ReferenceId
*/
void updateImage(MultipartFile file, FileRequest fileRequest);

/**
* 이미지 수정 : 여러 개의 이미지 중 하나를 수정
* @param file 수정된 파일
* @param updateTargetId 수정할 파일 id
*/
void updateImageById(MultipartFile file, Long updateTargetId);

/**
* 이미지 수정 : 여러개의 이미지 전체 삭제 후 전체 추가
* @param files 이미지 리스트
* @param fileRequest 수정할 위치
*/
void updateImagesAtOnce(List<MultipartFile> files, FileRequest fileRequest);

/**
* 파일 삭제
* @param fileRequest 삭제할 파일 위치: ReferenceType, ReferenceId
* @return 삭제 여부
*/
boolean deleteFile(FileRequest fileRequest);

/**
* 파일 삭제 여러개
* @param fileRequest 삭제할 파일 위치: ReferenceType, ReferenceId
* @return 삭제 여부
*/
boolean deleteFiles(FileRequest fileRequest);

/**
* 파일 삭제 아이디로
* @param fileId 삭제할 파일 아이디
* @return 삭제 여부
*/
boolean deleteFileById(Long fileId);

}
Loading

0 comments on commit cb58be1

Please sign in to comment.