안녕하세요, 코린이의 코딩 학습기 채니 입니다.
개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.
파일 업로드 처리
a. 서버 컴퓨터 저장
// spring의 빈으로 등록 되어있음
@Autowired
ServletContext application;
@PostMapping("/boardEnroll.do")
public String boardEnroll(Board board, @RequestParam(name = "upFile") List<MultipartFile> upFileList, RedirectAttributes redirectAttr) throws IllegalStateException, IOException {
for(MultipartFile upFile : upFileList) {
// log.debug("upFile = {}", upFile);
// log.debug("upFile#name = {}", upFile.getName());
// log.debug("upFile#originalFilename = {}", upFile.getOriginalFilename());
// log.debug("upFile#size = {}", upFile.getSize());
// 파일이 없어도 빈 객체가 넘어오므로 분기처리!
if(!upFile.isEmpty()) {
// a. 서버컴퓨터 저장
String saveDirectory = application.getRealPath("/resources/upload/board");
String renamedFilename = HelloSpringUtils.getRenamedFilename(upFile.getOriginalFilename()); // 20220830_141822222_123.txt
File destFile = new File(saveDirectory, renamedFilename); // 해당 경로에 해당 이름을 가진 파일객체
upFile.transferTo(destFile); // 해당 경로에 파일을 저장
ServletContext는 빈으로 등록 되어있기 때문에 의존 주입 받아 사용하였습니다.
저장 위치를 "/resource/upload/board"로 지정해주었으며, 커스텀 파일명을 생성하여 해당 경로에 해당 이름을 가진 파일을 저장하였습니다.
HelloSpringUtils
getRenamedFilename()
public static String getRenamedFilename(String originalFilename) {
// 확장자 추출
int beginIndex = originalFilename.lastIndexOf(".");
String ext = "";
if(beginIndex > -1) {
ext = originalFilename.substring(beginIndex); // .txt
}
// 새이름 생성
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmssSSS_");
DecimalFormat df = new DecimalFormat("000");
return sdf.format(new Date()) + df.format(Math.random()*1000) + ext;
}
b. DB 저장을 위한 Attachment 객체 생성
// b. DB저장을 위해 Attachment객체 생성
Attachment attachment = new Attachment(upFile.getOriginalFilename(), renamedFilename);
board.add(attachment);
}
}
log.debug("board = {}", board);
@콘솔출력값
DEBUG: com.ce.spring2.board.controller.BoardController - board = Board(super=BoardEntity(no=0, title=abc, memberId=honggd, content=def, readCount=0, createdAt=null, updatedAt=null), attachCount=0, attachments=[Attachment(no=0, boardNo=0, originalFilename=캠핑장 양도 시퀀스(최종).mdj, renamedFilename=20220830_143151189_255.mdj, downloadCount=0, createdAt=null), Attachment(no=0, boardNo=0, originalFilename=2022-03-03.png, renamedFilename=20220830_143151198_923.png, downloadCount=0, createdAt=null)])
서버 컴퓨터에 잘 저장된 것을 확인할 수 있습니다.
DB 저장
Controller
BoardController
@PostMapping("/boardEnroll.do")
public String boardEnroll(Board board, @RequestParam(name = "upFile") List<MultipartFile> upFileList, RedirectAttributes redirectAttr) throws IllegalStateException, IOException {
for(MultipartFile upFile : upFileList) {
// log.debug("upFile = {}", upFile);
// log.debug("upFile#name = {}", upFile.getName());
// log.debug("upFile#originalFilename = {}", upFile.getOriginalFilename());
// log.debug("upFile#size = {}", upFile.getSize());
// 파일이 없어도 빈 객체가 넘어오므로 분기처리!
if(!upFile.isEmpty()) {
// a. 서버컴퓨터 저장
String saveDirectory = application.getRealPath("/resources/upload/board");
String renamedFilename = HelloSpringUtils.getRenamedFilename(upFile.getOriginalFilename()); // 20220830_141822222_123.txt
File destFile = new File(saveDirectory, renamedFilename); // 해당 경로에 해당 이름을 가진 파일객체
upFile.transferTo(destFile); // 해당 경로에 파일을 저장
// b. DB저장을 위해 Attachment객체 생성
Attachment attachment = new Attachment(upFile.getOriginalFilename(), renamedFilename);
board.add(attachment);
}
}
log.debug("board = {}", board);
int result = boardService.insertBoard(board);
redirectAttr.addFlashAttribute("msg", "게시글을 성공적으로 등록했습니다.");
return "redirect:/board/boardList.do";
}
Service
BoardService interface 생략
BoardServiceImpl
@Override
public int insertBoard(Board board) {
// insert board
int result = boardDao.insertBoard(board);
// insert Attachment
List<Attachment> attachments = board.getAttachments();
if(!attachments.isEmpty()) {
for(Attachment attach : attachments) {
attach.setBoardNo(board.getNo());
result = boardDao.insertAttachment(attach);
}
}
return result;
}
Dao
BoardDao interface
@Insert("insert into board values(seq_board_no.nextval, #{title}, #{memberId}, #{content}, default, default, default")
@SelectKey(statement = "select seq_board_no.currval from dual", before = false, keyProperty = "no", resultType = int.class)
int insertBoard(Board board);
@Insert("insert into attachment values(seq_attahcment_no.nextval, #{boardNo}, #{originalFilename}, #{renamedFilename}, default, default")
int insertAttachment(Attachment attach);
attachment 테이블에 방금 저장된 board_no 컬럼이 필요하기 때문에 @SelectKey를 이용하여 해당 값을 가져와 처리해주었습니다.
statement = "select seq_board_no.currval from dual"를 @Insert 처리 후에(before = false), int 형으로 변환하여(resultType = int.class) Board의 setNo (KeyProperty = "no") 해주세요. 를 의미합니다.
따라서 Board 객체에 no 컬럼이 방금 저장된 no컬럼으로 지정되어있으므로 해당 값을 이용하여 attachment 테이블의 board_no 컬럼을 처리하였습니다.
서버 컴퓨터 및 db에 성공적으로 저장된 것을 확인할 수 있으며, attachment 테이블의 board_no 또한 잘 연결되어있습니다.
'Java > Spring' 카테고리의 다른 글
Spring) 2개 이상 테이블 조회(JOIN) - association, collection (0) | 2022.09.02 |
---|---|
Spring) 트랜잭션 처리 - @Transactional (0) | 2022.08.31 |
Spring) 게시글 작성 - 파일 업로드 처리를 위한 설정 (0) | 2022.08.30 |
Spring) 페이징 처리 (content, pagebar 영역) - RowBounds (0) | 2022.08.30 |
Spring) AOP - 특정 메소드 소요시간 계산, Escaping 처리, ErrorLog처리 (0) | 2022.08.28 |