11_spring_(★파일수정)

study/Spring · 2020. 3. 13. 08:51

Controller

// 게시글 수정 화면 이동
@RequestMapping("updateForm")
public String updateForm(Integer no, // 수정화면에 보여질 게시글 조회용 글번호
	Model model, // 게시글 정보 + 이미지 파일 정보를 View에 전달
    HttpServletRequest request // 수정 완료 후 상세보기로 돌아가기위한
    							// 상세보기 페이지주소(이전페이지주소)저장
    	) {
    // 이전 페이지(상세조회 페이지) 주소를 detailUrl에 저장
    String detailUrl = request.getHeader("referer");
    
    // @SessionAttributes에 "detailUrl" 추가 후
    // Session에 detailUrl 올리기
    model,addAttribute("detailUrl", detailUrl);
    
    try {
    	// 1) 게시글 상세 조회
        Board board = boardService.selectBoard(no);
        // 2) 게시글 상세 조회 성공 시 파일목록 조회
        if(board != null) {
        	List<Attachment> files = boardService.selectFiles(no);
            
            if(!files.isEmpty()) { //해당 게시글에 이미지가 있다면
            	model.addAttribute("files", files);
            }
        }
        
        // 3) 조회된 정보를 View에 전달 후 Forward
        // 개행 문자 변경
        board.setBoardContent(board.getBoardContent.replace("<br>","\r\n"));
        model.addAttribute("board",board);
        return "board/boardUpdate";
    } catch (Exception e) {
    	e.printStackTrace();
        model.addAttribute("errorMsg", "게시글수정화면전환과정에러발생");
        return "common/errorPage";
    }
}
            
// 게시글 수정
@RequestMapping("update"
public String updateBoard(Integer no, // 수정할 글 번호
		Board board, // View에서 전달된 게시글 수정 내용(커맨드 객체)
        Model model, // errorMsg 전달용도
        RedirectAttributes rdAttr, //수정 성공, 실패시 메세지 전달용도
        HttpServletRequest request, //수정 또는 새로 추가된 파일 저장을
        							// 위한 파일경로 추출용도
        @RequestParam(value="thumbnail", required=false)
        MultipartFile thumbnail,
        @RequestParam(value="images", required=false)
        List<MultipartFile> images
        ) {
    
    // 1) Session scope에서 detailUrl 얻어오기
    // -> 수정을 성공하든 실패하든 상세조회 다시 리다이렉트 하기 위함
    String detailUrl = request.getHeader("referer");
    
    // 2) no(글번호) board(커맨드객체)에 set(재활용)
    board.setBoardNo(no);
    
    // 3) 수정 또는 새롭게 추가된 파일이 저장될 경로 얻어오기
    String root = request.getSession().getServletContext().getRealPath("resources");
    String savePath = root + "/uploadFiles";
    
    // 저장될 폴더 선택
    File folder = new file(savePath);
    // 없을 경우 생성
    if(!folder.isExist()) folder.mkdir();
    
    try {
    	// 4) 게시글(+게시글 이미지) 수정용 서비스 호출
        int result = boardService.updateBoard(
        	board, thumbnail, images, savePath);
        
        // 5) 서비스 호출 결과에 따른 메세지 처리
        String msg = null;
        if(result > 0 ) {
        	msg = "게시글 수정 성공";
        else {
        	msg = "게시글 수정 실패;
        }
    	rdAttr.addFlashAttribute("msg", msg);
        
        // 수정 후 상세조회 화면 요청
        return "redirect:"+detailUrl;
    } catch (Exception e) {
        e.printStackTrace();
        model.addAttribute("errorMsg", 
        "게시글 수정 과정에서 오류 발생");
        return "common.errorPage";
	}
}
    
    
    

★BoardServiceImple

@Transactional(rollbackFor = Exception.class)
@Override
public int updateBoard(Board board, MultipartFile thumbnail, 
	List<MultipartFile> images, String savePath) throws Exception {
    
    // 기존 게시글 이미지 정보를 DB에서 조회
    List<Attachment> files = boardDAO.select(board.getBoardNo());
    			// 썸네일 + 일반 이미지
    // 썸네일, 일반 이미지 분리
    Attachment beforeTh = null;
    List<Attachment> beforeImages = new ArrayList<Attachment>();
    
    for(Attachment at : files) {
    	if(at.getFileLevel() == 0) {
        	beforeTh = at;
        else {
        	beforeImages.add(at);
        }
    }
    
    // 새롭게 삽입할 파일 목록(insert)
    List<Attachment> insertList = new ArrayList<Attachment>();
    
    // 기존행을 수정할 파일 목록(update)
    List<Attachment> updateList = new ArrayList<Attachment>();
    
    // 리스트에 추가될 Attachment 객체를 참조할 변수 선언
    Attachment file = null;
    
    // 썸네일 비교
    // 새롭게 등록된 썸네일이 있는지 확인
    // 썸네일 신규 존재(없으면 빈문자열)
    if(!thumbnail.getOriginFilename().equlas("")) {
    	// rename 작업 진행
        String changeFileName = FileRename.rename(thumbnail.getOriginalFileName());
        // 썸네일 기존 O --> update 진행
        if(beforeTh != null) {
        	file = new Attachment(beforeTh.getFileNo(),
            		thumbnail.getOriginalFilename(),
                    changeFileName);
                    
            file.setFileLevel(0); // 썸네일 파일레벨은 0
            updateList.add(file);
        }
        
        // 썸네일 기존 x --> insert 진행
        else {
        	file = new Attachment(thumbnail.getOriginalFilename(),
            		changeFileName, savePath);
            file.setFileLevel(0); // 썸네일 파일레벨은 0
            file.setBoardId(board.getBoardNo());
            insertList.add(file);
        }
    }
    
    //일반 이미지 비교
    int filesIndex = 0;
    // 기존 파일 목록(beforeImages)에 얻어올 인덱스 값을 저장할 변수 선언
    
    for(int i=0; i<images.size(); i++) {
    	// 일반 이미지 신규 o
        if(!images.get(i).getOriginalFilename().equals("")) {
        	
            // rename 처리
            String changeFilename = FileRename.rename(
            							images.get(i).getOriginalFilename());
            
            // 일반 이미지 기존 o (update)
            if(beforeImages.size() > 0 && i<beforeImages.size()) {
            	file = new Attachment(
                		beforeImages.get(filesIndex).getFileNo(),
                        images.get(i).getOriginalFilename(),
                        changeFileName);
                file.setFileLevel(1);
                updateList.add(file);
                fileIndex++;
            }
            
            // 일반 이미지 기존 X --> insert
            else {
            	file = new Attachment(
                		images.get(i).getOriginalFilename(),
                        changeFileName,
                        savePath);
          		
                file.setFileLevel(1);
                file.setBoardId(board.getBoardNo());
                // 신규 파일은 boardId가 없으므로 추가
                insertList.add(file);
            }
        }
    }
    
    // 1) 게시글 수정
    // 개행문자 변환 (\r\n -> <br>)
    board.setBoardContent(
    	board.getBoardContent.replace("\r\n" -> "<br>"));
        
    result = boardDAO.updateBoard(board);
    
    // 2) 게시글 수정 성공 & 새로 삽입할 파일(insertList)가 있을 경우
    if(result > 0 && !insertList.isEmpty()) {
    	result = 0; // result 재활용
        
        for(Attachment at: insertList) {
        	result = boardDAO.insertAttachment(at);
            
            if(result == 0) {
            	throw new Exception("파일 삽입 과정에서 오류발생");
            }
        }
    }
    
    // 3) 기존 Attachment 테이블 수정할 파일정보(updateList)가 있을경우
    if(result>0 && !updateList.isEmpty())
    	result = 0; // result 재활용
        
        for(Attachment at : updateList) {
        	result = boardDAO.updateAttachment(at);
            
            if(result == 0) {
            	throw new Exception("파일 수정 과정에서 오류 발생");
            }
        }
    }
    
    // 4) DB 수정이 정상적으로 처리된 경우 파일저장
    if(result > 0) {
    	// insertList, updateList 합치기
        insertList.addAll(updateList);
        
        for(Attachment at : insertList) {
        	if(at.getFileLevel() == 0) { // 현재 접근한 파일이 썸네일이면
            	thumbnail.transferTo(new File(savePath + "/" + at.getFileChangeName()));
            } else { // 현재 접근한 파일이 일반이미지라면
            	for(MultipartFile mf : images) {
                	if(mf.getOriginalFilename().equals(at.getFileOriginName()))){
                    	mf.transferTo(new File(savePath + "/" + at.getFileChangeName()));
                        break;
                    }
                }
            }
        }
    }
    
    // 수정 전 이미지를 서버에서 삭제
    for(Attachment at : files) { // 수정 전 이미지 목록 반복 접근
    	for(Attachment newImages : insertList) { // 수정후 이미지목록 반복접근
        	
            // 수정 전 fileNo와 수정 후 fileNo가 같은 객체가 존재하는 경우
            // --> 수정 전 파일에서 changeFileName을 얻어와 서버에서 삭제
            if(at.getFileNo() == newImage.getFileNo()) {
            	// 이미지 삭제
                File deleteFile = new File(savePath + "/" + at.getFileChangeName());
                deleteFile.delete();
            }
        }
    }
    return result;
}
    

boardDAO

	/** 게시글 수정용 DAO
	 * @param board
	 * @return result
	 * @throws Exception
	 */
	public int updateBoard(Board board) throws Exception{
		return sqlSession.update("boardMapper.updateBoard", board);
	}


	/** 파일 수정용 DAO
	 * @param at
	 * @return result
	 * @throws Exception
	 */
	public int updateAttachment(Attachment at) throws Exception{
		return sqlSession.update("boardMapper.updateAttachment", at);
	}

boardMapper

	<!-- 게시글 수정 -->
	<update id="updateBoard" parameterType="Board">
		UPDATE BOARD SET 
		BOARD_TITLE = #{boardTitle},
		BOARD_CONTENT = #{boardContent},
		BOARD_CATEGORY = #{boardCategory},
		BOARD_MODIFY_DT = SYSDATE
		WHERE BOARD_NO = #{boardNo}
	</update>
	
	<!-- 파일 수정 -->
	<update id="updateAttachment" 
		parameterType="Attachment">
		UPDATE ATTACHMENT SET
		FILE_ORIGIN_NAME = #{fileOriginName},
		FILE_CHANGE_NAME = #{fileChangeName},
		FILE_UPLOAD_DATE = SYSDATE
		WHERE FILE_NO = #{fileNo}
	</update>

'study > Spring' 카테고리의 다른 글

13_spring_(AOP)  (0) 2020.03.17
12_spring_(ajax사용한 댓글)  (0) 2020.03.16
10_spring_(파일조회)  (0) 2020.03.12
9_Spring(파일업로드2)  (0) 2020.03.11
8_Spring(파일업로드1)  (0) 2020.03.09