최초 시도(중복 덮어쓰기 발생)
중복 허용을 위하여 noticeId를 기준으로 UUID 추가
multipart 파일 업로드는 필수라 첨부없이 일반 공지를 못올리는 문제 발생
// 공지글 생성
@PostMapping("/create")
public StatusResponseDto createNotice(@ModelAttribute NoticeCreateRequestDto requestDto,
@RequestParam(required = false) MultipartFile file) throws IOException {
return noticeService.createNotice(requestDto, file);
}
JavaScript
복사
required=false 를 통해서 파일첨부가 없는 공지사항도 생성 가능하도록 변경
하지만 서버측 오류 발생, 다만 공지는 추가되고 파일은 업로드된 유도한 상황
우선 JS쪽에서도 FormData에 file이 없는 경우에 alert를 하지 않도록 허용
function createNotice() {
// 폼 필드에서 값을 읽어와서 변수에 저장
const boardId = $('#boardId').val();
const writer = "관리자";
const title = $('#noticeTitle').val();
const type = $('#noticeType').val();
const contents = $('#noticeContents').val();
const requestData = {
boardId: boardId,
noticeWriter: writer,
noticeTitle: title,
noticeType: type,
noticeContents: contents
};
const formData = new FormData();
// 파일이 선택된 경우에만 FormData에 추가
const fileInput = document.getElementById('file');
if (fileInput.files.length > 0) {
formData.append('file', fileInput.files[0]);
}
formData.append('boardId', boardId);
formData.append('noticeWriter', writer);
formData.append('noticeTitle', title);
formData.append('noticeType', type);
formData.append('noticeContents', contents);
$.ajax({
type: 'POST',
url: '/api/boards/notice/create',
data: formData,
contentType: false, // 필수
processData: false, // 필수
success: function (response) {
alert('공지 추가 성공!');
window.location.reload();
},
error: function (xhr, status, error) {
alert('공지 추가 실패!');
console.error('Error:', error);
}
});
}
JavaScript
복사
여전히 공지는 추가되지만 오류는 나타나는상황,
아무래도 noticeService 부분에서 fileRepository로 넘기는 부분에 file!=null 과 같이 접근해야 할 것 같다.
// 파일이 선택된 경우에만 파일 처리
if (file != null) {
String originalFileName = file.getOriginalFilename();
// UUID와 파일명 조합
String uniqueFileName = noticeUUID + "_" + originalFileName;
String filePath = fileService.uploadFile(file, uniqueFileName);
// 파일 정보를 Notice 엔티티에 추가
File fileEntity = new File(uniqueFileName, file.getSize(), FileTypeEnum.IMG, filePath);
notice.addFile(fileEntity);
// 파일 엔티티 저장
fileRepository.save(fileEntity);
}
JavaScript
복사
File이 없는 경우에도 오류메시지가 안나타나도록 조건문설정
다시 파일이 있는경우엔 파일이 참조되도록 테스트
파일이 첨부된 공지에서의 현재 파일에 대한 정보 조회(조회 일부)
FileResponseDto를 통한 공지로부터 파일의 조회(공지:파일 = 1:N) 연관관계를 통한 조회
@Getter
@NoArgsConstructor
public class NoticeResponseDto {
...
@OneToMany(mappedBy = "notice")
List<File> fileList = new ArrayList<>();
...
public NoticeResponseDto(Notice notice){
this.noticeId = notice.getNoticeId();
this.formattedCreatedAt = formatDateTime(notice.getCreatedAt());
this.noticeTitle = notice.getNoticeTitle();
this.noticeWriter = notice.getNoticeWriter();
this.noticeContents = notice.getNoticeContents();
this.noticeType = notice.getNoticeType();
// Notice 엔티티에서 fileList를 가져와 FileResponseDto로 변환하여 할당
this.fileList = FileResponseDto.fromFileList(notice.getFileList());
}
}
JavaScript
복사
@Getter
@NoArgsConstructor
public class FileResponseDto {
private Long fileId;
private String fileName;
private Long fileSize;
private String fileType;
private String fileUrl;
public FileResponseDto(File file) {
this.fileId = file.getId();
this.fileName = file.getFileName();
this.fileSize = file.getFileSize();
this.fileType = file.getFileType().name();
this.fileUrl = file.getFileUrl();
}
public static List<FileResponseDto> fromFileList(List<File> fileList) {
return fileList.stream()
.map(FileResponseDto::new)
.collect(Collectors.toList());
}
}
JavaScript
복사