Skip to content

Commit c257696

Browse files
authored
Fix: 프론트 요청사항에 따른 파일 업로드 기능 수정
* Fix: 파일 업로드 요청 데이터 변경 - 기존: 파일 정보 + 엔티티 타입 + 해당 엔티티의 아이디 - 변경: 유저 + 파일 정보 * Fix: 파일 업로드 로직 변경 - 요청 데이터 변경에 따른 로직 변경 * Fix: 파일 업로드 응답 데이터 변경 - 기존: publicURL - 변경: attachmentId + publicURL * Fix: 파일 업로드 컨트롤러 메서드 변경 - 파일 업로드 요청 및 응답 데이터 변경에 따른 컨트롤러 메서드 변경 * Fix: FileAttachment 엔티티 필드명 변경 - 기존 : filePath - 변경 : publicURL * Fix: 파일 조회 엔드포인트 변경 - 기존: /api/file/read?entityType=POST&entityId=1 - 변경: /api/file/read/{attachmentId} * Fix: 파일 조회 로직 변경 - 엔드 포인트 변경에 따른 파일 조회 비즈니스 로직 변경 * Fix: 파일 업데이트 엔트포인트 수정 - 기존 : /api/file/update - 변경 : /api/file/update/{attachmentId} * Fix: 파일 수정 컨트롤러 메서드 변경 - 엔드 포인트 변경에 따른 파일 수정 컨트롤러 메서드 변경 * Fix: 파일 수정 로직 변경 - 엔드 포인트 변경에 따른 파일 수정 로직 변경 * Fix: 응답 데이터 수정 - 기존: null - 변경: publicURL * Fix: 파일 삭제 엔드 포인트 변경 - 기존: /api/file/delete?entityType=POST&entityId=1 - 변경: /api/file/delete/{attachmentId} * Fix: 파일 삭제 로직 변경 - 엔드 포인트 변경에 따른 파일 삭제 로직 변경 * Chore: 파일 서비스 쓰지않는 메서드/ 의존성 필드 삭제 - AttachmentMappingRepository 삭제 - getFileAttachmentOrThrow(AttachmentMapping으로부터 파일정보 추출하는 함수) 삭제 * Fix: 파일 서비스 테스트 수정 - 파일 서비스 변경에 따른 테스트 수정 * Fix: 파일 조회/수정 응답메시지 변경 - 기존: imageUrl = "S3 퍼블릭 URL" - 변경: publicURL = "S3 퍼블릭 URL" * Fix: CORS 설정 변경 프론트 운영서버 반영 * Test: 파일 컨트롤러 테스트 추가 * Fix: 파일 접근 권한 체크 기존 : "!=" 비교 변경 : "equals" 비교
1 parent 3ca927a commit c257696

File tree

12 files changed

+405
-139
lines changed

12 files changed

+405
-139
lines changed

src/main/java/com/back/domain/file/controller/FileController.java

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ public ResponseEntity<RsData<FileUploadResponseDto>> uploadFile(
2929
) {
3030
FileUploadResponseDto res = fileService.uploadFile(
3131
req.getMultipartFile(),
32-
req.getEntityType(),
33-
req.getEntityId(),
3432
user.getUserId()
3533
);
3634

@@ -39,44 +37,41 @@ public ResponseEntity<RsData<FileUploadResponseDto>> uploadFile(
3937
.body(RsData.success("파일 업로드 성공", res));
4038
}
4139

42-
@GetMapping(value = "/read")
40+
@GetMapping(value = "/read/{attachmentId}")
4341
public ResponseEntity<RsData<FileReadResponseDto>> getFile(
44-
@RequestParam("entityType") @NotBlank(message = "entityType은 필수입니다.") EntityType entityType,
45-
@RequestParam("entityId") @NotBlank(message = "entityId는 필수입니다.") Long entityId
42+
@PathVariable("attachmentId") Long attachmentId
4643
) {
47-
FileReadResponseDto res = fileService.getFile(entityType, entityId);
44+
FileReadResponseDto res = fileService.getFile(attachmentId);
4845

4946
return ResponseEntity
5047
.status(HttpStatus.OK)
5148
.body(RsData.success("파일 조회 성공", res));
5249
}
5350

54-
@PutMapping(value = "/update", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
55-
public ResponseEntity<RsData<Void>> updateFile(
51+
@PutMapping(value = "/update/{attachmentId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
52+
public ResponseEntity<RsData<FileUpdateResponseDto>> updateFile(
53+
@PathVariable("attachmentId") Long attachmentId,
5654
@ModelAttribute @Valid FileUpdateRequestDto req,
5755
@AuthenticationPrincipal CustomUserDetails user
5856
) {
59-
fileService.updateFile(
57+
FileUpdateResponseDto res = fileService.updateFile(
58+
attachmentId,
6059
req.getMultipartFile(),
61-
req.getEntityType(),
62-
req.getEntityId(),
6360
user.getUserId()
6461
);
6562

6663
return ResponseEntity
6764
.status(HttpStatus.OK)
68-
.body(RsData.success("파일 업데이트 성공"));
65+
.body(RsData.success("파일 업데이트 성공", res));
6966
}
7067

71-
@DeleteMapping(value = "/delete")
68+
@DeleteMapping(value = "/delete/{attachmentId}")
7269
public ResponseEntity<RsData<Void>> deleteFile(
73-
@RequestParam("entityType") @NotBlank(message = "entityType은 필수입니다.") EntityType entityType,
74-
@RequestParam("entityId") @NotBlank(message = "entityId는 필수입니다.") Long entityId,
70+
@PathVariable("attachmentId") Long attachmentId,
7571
@AuthenticationPrincipal CustomUserDetails user
7672
) {
7773
fileService.deleteFile(
78-
entityType,
79-
entityId,
74+
attachmentId,
8075
user.getUserId()
8176
);
8277

src/main/java/com/back/domain/file/dto/FileReadResponseDto.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
@Data
66
public class FileReadResponseDto {
7-
private String imageUrl;
7+
private String publicURL;
88

9-
public FileReadResponseDto(String imageUrl) {
10-
this.imageUrl = imageUrl;
9+
public FileReadResponseDto(String publicURL) {
10+
this.publicURL = publicURL;
1111
}
1212
}

src/main/java/com/back/domain/file/dto/FileUpdateRequestDto.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,4 @@
1010
public class FileUpdateRequestDto {
1111
@NotNull(message = "파일 입력은 필수입니다.")
1212
private MultipartFile multipartFile;
13-
14-
private EntityType entityType;
15-
16-
private Long entityId;
1713
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.back.domain.file.dto;
2+
3+
import lombok.Data;
4+
5+
@Data
6+
public class FileUpdateResponseDto {
7+
private String publicURL;
8+
9+
public FileUpdateResponseDto(String publicURL) {
10+
this.publicURL = publicURL;
11+
}
12+
}

src/main/java/com/back/domain/file/dto/FileUploadRequestDto.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,4 @@
1010
public class FileUploadRequestDto {
1111
@NotNull(message = "파일 입력은 필수입니다.")
1212
private MultipartFile multipartFile;
13-
14-
private EntityType entityType;
15-
16-
private Long entityId;
1713
}

src/main/java/com/back/domain/file/dto/FileUploadResponseDto.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44

55
@Data
66
public class FileUploadResponseDto {
7-
private String imageUrl;
7+
private Long attachmentId;
8+
private String publicURL;
89

9-
public FileUploadResponseDto(String imageUrl) {
10-
this.imageUrl = imageUrl;
10+
public FileUploadResponseDto(Long attachmentId, String publicURL) {
11+
this.attachmentId = attachmentId;
12+
this.publicURL = publicURL;
1113
}
1214
}

src/main/java/com/back/domain/file/entity/FileAttachment.java

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public class FileAttachment extends BaseEntity {
1818

1919
private String originalName;
2020

21-
private String filePath;
21+
private String publicURL;
2222

2323
private long fileSize;
2424

@@ -36,25 +36,21 @@ public FileAttachment(
3636
String storedName,
3737
MultipartFile multipartFile,
3838
User user,
39-
EntityType entityType,
40-
Long entityId,
41-
String filePath
39+
String publicURL
4240
) {
4341
this.storedName = storedName;
44-
originalName = multipartFile.getOriginalFilename();
45-
this.filePath = filePath;
46-
fileSize = multipartFile.getSize();
42+
this.originalName = multipartFile.getOriginalFilename();
43+
this.publicURL = publicURL;
44+
this.fileSize = multipartFile.getSize();
4745
this.contentType = multipartFile.getContentType();
4846
this.user = user;
49-
50-
attachmentMappings.add(new AttachmentMapping(this ,entityType, entityId));
5147
}
5248

53-
public void update(String storedName, MultipartFile multipartFile, String filePath) {
49+
public void update(String storedName, MultipartFile multipartFile, String publicURL) {
5450
this.storedName = storedName;
55-
originalName = multipartFile.getOriginalFilename();
56-
this.filePath = filePath;
57-
fileSize = multipartFile.getSize();
51+
this.originalName = multipartFile.getOriginalFilename();
52+
this.publicURL = publicURL;
53+
this.fileSize = multipartFile.getSize();
5854
this.contentType = multipartFile.getContentType();
5955
}
6056
}

src/main/java/com/back/domain/file/service/FileService.java

Lines changed: 27 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.amazonaws.services.s3.model.ObjectMetadata;
66
import com.amazonaws.services.s3.model.PutObjectRequest;
77
import com.back.domain.file.dto.FileReadResponseDto;
8+
import com.back.domain.file.dto.FileUpdateResponseDto;
89
import com.back.domain.file.dto.FileUploadResponseDto;
910
import com.back.domain.file.entity.AttachmentMapping;
1011
import com.back.domain.file.entity.EntityType;
@@ -20,6 +21,8 @@
2021
import org.springframework.beans.factory.annotation.Value;
2122
import org.springframework.stereotype.Service;
2223
import org.springframework.transaction.annotation.Transactional;
24+
import org.springframework.web.bind.annotation.PathVariable;
25+
import org.springframework.web.bind.annotation.RequestParam;
2326
import org.springframework.web.multipart.MultipartFile;
2427

2528
import java.io.IOException;
@@ -34,14 +37,10 @@ public class FileService {
3437
private final AmazonS3 amazonS3;
3538
private final FileAttachmentRepository fileAttachmentRepository;
3639
private final UserRepository userRepository;
37-
private final AttachmentMappingRepository attachmentMappingRepository;
38-
private final EntityValidator entityValidator;
3940

4041
@Transactional
4142
public FileUploadResponseDto uploadFile(
4243
MultipartFile multipartFile,
43-
EntityType entityType,
44-
Long entityId,
4544
Long userId
4645
) {
4746
User user = userRepository.findById(userId)
@@ -53,46 +52,44 @@ public FileUploadResponseDto uploadFile(
5352
String storedFileName = createFileName(multipartFile.getOriginalFilename());
5453

5554
// S3의 저장된 파일의 PublicURL
56-
String filePath = s3Upload(storedFileName, multipartFile);
55+
String publicURL = s3Upload(storedFileName, multipartFile);
5756

5857
// FileAttachment 정보 저장
59-
fileAttachmentRepository.save(
58+
FileAttachment fileAttachment = fileAttachmentRepository.save(
6059
new FileAttachment(
6160
storedFileName,
6261
multipartFile,
6362
user,
64-
entityType,
65-
entityId,
66-
filePath
63+
publicURL
6764
)
6865
);
6966

70-
return new FileUploadResponseDto(filePath);
67+
return new FileUploadResponseDto(fileAttachment.getId(), publicURL);
7168
}
7269

7370

7471
@Transactional(readOnly = true)
75-
public FileReadResponseDto getFile(
76-
EntityType entityType,
77-
Long entityId
78-
) {
79-
FileAttachment fileAttachment = getFileAttachmentOrThrow(entityType, entityId);
72+
public FileReadResponseDto getFile(Long attachmentId) {
73+
FileAttachment fileAttachment = fileAttachmentRepository.findById(attachmentId)
74+
.orElseThrow(() ->
75+
new CustomException(ErrorCode.FILE_NOT_FOUND)
76+
);
8077

81-
String filePath = fileAttachment.getFilePath();
78+
String publicURL = fileAttachment.getPublicURL();
8279

83-
return new FileReadResponseDto(filePath);
80+
return new FileReadResponseDto(publicURL);
8481
}
8582

8683
@Transactional
87-
public void updateFile(
84+
public FileUpdateResponseDto updateFile(
85+
Long attachmentId,
8886
MultipartFile multipartFile,
89-
EntityType entityType,
90-
Long entityId,
9187
Long userId
9288
) {
93-
entityValidator.validate(entityType, entityId);
94-
95-
FileAttachment fileAttachment = getFileAttachmentOrThrow(entityType, entityId);
89+
FileAttachment fileAttachment = fileAttachmentRepository.findById(attachmentId)
90+
.orElseThrow(() ->
91+
new CustomException(ErrorCode.FILE_NOT_FOUND)
92+
);
9693

9794
checkAccessPermission(fileAttachment, userId);
9895

@@ -102,26 +99,22 @@ public void updateFile(
10299
// S3에 새롭게 저장할 파일 이름
103100
String newStoredName = createFileName(multipartFile.getOriginalFilename());
104101

105-
String filePath = s3Upload(newStoredName, multipartFile);
102+
String publicURL = s3Upload(newStoredName, multipartFile);
106103

107104
s3Delete(oldStoredName);
108105

109106
// fileAttachment 정보 업데이트
110-
fileAttachment.update(newStoredName, multipartFile, filePath);
107+
fileAttachment.update(newStoredName, multipartFile, publicURL);
108+
return new FileUpdateResponseDto(publicURL);
111109
}
112110

113111
@Transactional
114-
public void deleteFile(EntityType entityType, Long entityId, Long userId) {
115-
entityValidator.validate(entityType, entityId);
116-
117-
AttachmentMapping attachmentMapping = attachmentMappingRepository
118-
.findByEntityTypeAndEntityId(entityType, entityId)
112+
public void deleteFile(Long attachmentId, Long userId) {
113+
FileAttachment fileAttachment = fileAttachmentRepository.findById(attachmentId)
119114
.orElseThrow(() ->
120-
new CustomException(ErrorCode.ATTACHMENT_MAPPING_NOT_FOUND)
115+
new CustomException(ErrorCode.FILE_NOT_FOUND)
121116
);
122117

123-
FileAttachment fileAttachment = attachmentMapping.getFileAttachment();
124-
125118
checkAccessPermission(fileAttachment, userId);
126119

127120
s3Delete(fileAttachment.getStoredName());
@@ -173,19 +166,8 @@ private String createFileName(String fileName) {
173166

174167
// 파일 접근 권한 체크
175168
private void checkAccessPermission(FileAttachment fileAttachment, Long userId) {
176-
if (fileAttachment.getUser().getId() != userId) {
169+
if (!fileAttachment.getUser().getId().equals(userId)) {
177170
throw new CustomException(ErrorCode.FILE_ACCESS_DENIED);
178171
}
179172
}
180-
181-
// AttachmentMapping -> fileAttachment 추출
182-
private FileAttachment getFileAttachmentOrThrow(EntityType entityType, Long entityId) {
183-
AttachmentMapping attachmentMapping = attachmentMappingRepository
184-
.findByEntityTypeAndEntityId(entityType, entityId)
185-
.orElseThrow(() ->
186-
new CustomException(ErrorCode.ATTACHMENT_MAPPING_NOT_FOUND)
187-
);
188-
189-
return attachmentMapping.getFileAttachment();
190-
}
191173
}

src/main/java/com/back/global/exception/ErrorCode.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ public enum ErrorCode {
143143
FILE_UPLOAD_FAILED(HttpStatus.INTERNAL_SERVER_ERROR, "FILE_001", "파일 업로드에 실패했습니다."),
144144
ATTACHMENT_MAPPING_NOT_FOUND(HttpStatus.NOT_FOUND, "FILE_002", "매핑된 파일 정보를 찾을 수 없습니다."),
145145
FILE_ACCESS_DENIED(HttpStatus.FORBIDDEN, "FILE_003", "파일을 접근할 권한이 없습니다."),
146+
FILE_NOT_FOUND(HttpStatus.NOT_FOUND, "FILE_004", "파일 정보를 찾을 수 없습니다."),
146147

147148
// ======================== 토큰 관련 ========================
148149
INVALID_EMAIL_TOKEN(HttpStatus.UNAUTHORIZED, "TOKEN_001", "유효하지 않은 이메일 인증 토큰입니다."),

src/main/java/com/back/global/security/SecurityConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public void addCorsMappings(CorsRegistry registry) {
8989
registry.addMapping("/**")
9090
.allowedOrigins(
9191
"http://localhost:3000", // Catfe 프론트 개발 서버
92-
"https://www.catfe.com" // Catfe 프론트 운영 서버
92+
"https://www.catfe.site" // Catfe 프론트 운영 서버
9393
)
9494
.allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS")
9595
.allowedHeaders("*")

0 commit comments

Comments
 (0)