개발 환경
- sts 4
- mybatis
- oracle xe 11g
요구사항
- 파일 업로드
- 각 게시글 업로드 시 파일 첨부
- 파일 저장 시 게시글 별로 폴더 새로 생성해서 저장
- uuid + 업로드 파일 이름 형식으로 파일 저장
- 파일 다운로드
- 다운로드 받을 때는 uuid가 없는 원본 파일 이름으로 다운로드
파일 업로드
// 컨트롤러
@PostMapping("/board/write")
public String insertBoard(BoardListDto dto, Model model, HttpSession session) throws Exception {
Long userId = (Long) session.getAttribute(SessionConst.USER_ID);
if (userId == null) {
throw new CustomException(-1, "로그인 정보가 없습니다.");
}
dto.setUserId(userId);
boardServiceImpl.insertBoard(dto);
return "redirect:/";
}
// 서비스
@Override
public int insertBoard(BoardListDto dto) throws Exception {
log.info("serviceImpl dto = {}", dto);
BoardListDto board = BoardListDto.builder()
.title(dto.getTitle())
.content(dto.getContent())
.files(dto.getFiles())
.commentCnt(dto.getCommentCnt())
.userId(dto.getUserId()) // 로그인한 // 이름 저장
.build();
// board 정보를 db 에 insert
int result = boardMapper.insertBoard(board);
// 파일 업로드 처리 : 각 게시글 마다 다른 폴더에 저장하기 위해 폴더를 생성하는 메서드 작성 후 활용
String boardFolderPath = createFolder(path, board.getBoardId());
File file = new File(boardFolderPath);
// 경로가 없을 경우 파일을 생성
if (!file.exists()) {
file.mkdirs();
}
for (MultipartFile f : board.getFiles()) {
if (!f.isEmpty()) {
log.info("file => {}", f.getOriginalFilename());
// HDD SAVE
String fileName = fileManager.saveFile(f, boardFolderPath);
// DB SAVE
UploadFileVO uploadFileVO = UploadFileVO.builder()
.orgFileName(f.getOriginalFilename())
.saveFileName(fileName)
.savePath(boardFolderPath)
.fileSize(f.getSize())
.boardId(board.getBoardId())
.build();
// file 정보를 db 에 insert
boardMapper.insertFile(uploadFileVO);
}
}
return result;
}
private String createFolder(String basePath, Long boardId) {
String folderPath = basePath + "/" + boardId;
File folder = new File(folderPath);
if (!folder.exists()) {
folder.mkdirs();
}
return folderPath;
}
Mapper
@Mapper
public interface BoardMapper {
// 첨부파일 업로드
public int insertFile(UploadFileVO fileVO) throws Exception;
}
mapper.xml
<!-- 첨부파일 업로드 -->
<insert id="insertFile" parameterType="fileVO">
INSERT INTO UPLOADFILE(
UPLOADFILE_ID,
BOARD_ID,
ORG_FILE_NAME,
SAVE_FILE_NAME,
SAVE_PATH,
FILE_SIZE
) VALUES(
UPLOADFILE_SEQ.nextval,
#{boardId},
#{orgFileName},
#{saveFileName},
#{savePath},
#{fileSize}
)
</insert>
파일 다운로드
// 파일 다운로드 처리
@GetMapping("/fileDownload/{boardId}/{saveFileName}/{orgFileName}")
public void fileDownload(@PathVariable String boardId, @PathVariable String saveFileName, @PathVariable String orgFileName, HttpServletResponse response)
throws IOException {
// 게시글 별로 폴더를 생성하여 파일을 따로 저장해줬으므로 @PathVariable 로 받아온 게시글의 id(폴더 이름), 저장된 파일 이름을 더해서 저장 경로를 수정한다.
String folderPath = path + "/" + boardId;
// 저장 경로와 불러올 파일의 이름을 파라미터로 넘겨 파일을 찾아온다.
File f = new File(folderPath, saveFileName);
log.info("folderPath = {}", folderPath);
// file 다운로드 설정
response.setContentType("application/download");
response.setContentLength((int) f.length());
// encoding 을 해줘야 파일 경로를 제대로 잘 찾아감.
String fileName = URLEncoder.encode(orgFileName, "UTF-8");
response.setHeader("Content-disposition", String.format("attachment; filename=\"%s\";", fileName) + "\"");
// response 객체를 통해서 서버로부터 파일 다운로드
OutputStream os = response.getOutputStream();
// 파일 입력 객체 생성
FileInputStream fis = new FileInputStream(f);
FileCopyUtils.copy(fis, os);
fis.close();
os.close();
}
'👩💻 BackEnd > 🌿 스프링 [Spring]' 카테고리의 다른 글
[ Spring ] Controller 에서 데이터를 어떤 형태로 받아야하는가? (@RequestBody, @RequestParam) (0) | 2024.05.21 |
---|---|
[ Spring / Spring Boot ] 스프링 인터셉터 활용하여 인가작업 처리하기 (0) | 2024.05.05 |
interceptor 3가지 메서드 (0) | 2024.05.04 |
[Spring MVC] spring mvc 실용적인 방식 (0) | 2024.01.19 |
[Spring MVC] DispatcherServlet / 핸들러 매핑과 핸들러 어댑터 (0) | 2024.01.19 |