Back-End/Java

[Spring] Legacy Project 첨부파일 구현하기

CJun 2021. 6. 15. 22:13
반응형
ATTACH 테이블 생성

 

AttachVO.java 생성
앞서 생성한 테이블의 구조를 객체화 시키기 위함

package com.example.domain;

import lombok.Data;

@Data
public class AttachVO {
	
	private String uuid;
	private String uploadpath;
	private String filename;
	private String filetype;
	private int bno;
	
}

 

AttachMapper.java
SQL문 insert 처리를 위한 메소드

package com.example.mapper;

import org.apache.ibatis.annotations.Insert;

import com.example.domain.AttachVO;

public interface AttachMapper {

	// 첨부파일정보 insert하기 메소드
	@Insert("INSERT INTO attach (uuid, uploadpath, filename, filetype, bno) "
			+ "VALUES (#{uuid}, #{uploadpath}, #{filename}, #{filetype}, #{bno})")
	public int insertAttach(AttachVO attachVO);
}

 

BoardController.java
// 주글쓰기 요청
	@GetMapping("/write")
	public String write(@ModelAttribute("pageNum") String pageNum) {
		 return "board/boardWrite";
	}
	
	// 주글쓰기 처리
	@PostMapping("/write")
	public String write(BoardVO boardVO, String pageNum, 
			HttpServletRequest request, RedirectAttributes rttr,
			List<MultipartFile> files) throws Exception {
		
		log.info("files 매개변수 : " + files);
		if (files != null) {
			log.info("업로드한 첨부파일 개수 : " + files.size());
		}
		
		// IP주소 값 저장
		boardVO.setIp(request.getRemoteAddr());
		
		// insert할 글번호 가져오기
		int num = boardService.nextBoardNum();
		
		boardVO.setNum(num);
		boardVO.setReadcount(0);
		boardVO.setRegDate(new Date());
		
		boardVO.setReRef(num); // 주글일 경우 [글그룹번호]는 글번호와 동일함
		boardVO.setReLev(0);  // 주글일 경우 [들여쓰기 레벨]은 0
		boardVO.setReSeq(0);  // 주글일 경우 [글그룹 안에서의 순서]는 0
		
		
		//=========== 파일 업로드 작업 시작 ==============
		
		ServletContext application = request.getServletContext();
		String realPath = application.getRealPath("/resources/upload");
		log.info("realPath : " + realPath);
		
		// 폴더 동적 생성하기 /resources/upload/2021/06/15
		File uploadPath = new File(realPath, getDateFolder());
		
		if (!uploadPath.exists()) {
			uploadPath.mkdirs();
		}
		
		for (MultipartFile multipartFile : files) {
			if (multipartFile.isEmpty()) {
				continue;
			}
			
			String uploadFilename = multipartFile.getOriginalFilename();
			
			UUID uuid = UUID.randomUUID();
			uploadFilename = uuid.toString() + "_" + uploadFilename;
			
			// 파일 업로드 수행
			multipartFile.transferTo(new File(uploadPath, uploadFilename));
			
		} // for
		
		//=========== 파일 업로드 작업 끝 ==============
		
		
		
		
		// 주글을 테이블에 insert하기
		//boardService.register(boardVO);
		//boardService.registerBoardAndAttaches(boardVO, null);
		
		// 리다이렉트 시 서버로 다시 전달할 데이터를 저장하기
		rttr.addAttribute("num", boardVO.getNum());
		rttr.addAttribute("pageNum", pageNum);
		
		return "redirect:/board/content";
	} // write post
	
	
	private String getDateFolder() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
		Date date = new Date();
		String str = sdf.format(date);
		return str;
	}

 

boardWrite.jsp

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>

<body>
    <!-- App -->
    <div id="app">

        <%-- include header.jsp --%>
		<jsp:include page="/WEB-INF/views/include/header.jsp" />
            
        <div class="container">
            <!-- Breadcrumbs -->
            <nav>
                <div class="nav-wrapper cyan">
                    <div class="col s12">
                        <a href="/" class="breadcrumb">홈</a>
                        <a href="/board/list?pageNum=${ pageNum }" class="breadcrumb">게시판 글목록</a>
                        <a href="/board/write" class="breadcrumb">게시판 글쓰기</a>
                    </div>
                </div>
            </nav>
            <!-- end of Breadcrumbs -->


            <!-- Forms -->
            <div class="row">
                <h4 class="center-align">게시판 새글쓰기</h4>
                <hr style="margin-bottom: 50px;">

                <form class="col s12 l6 offset-l3" action="/board/write" method="post" enctype="multipart/form-data">
                	<input type="hidden" name="pageNum" value="${ pageNum }">
                	
                    <div class="row">
                        <div class="input-field col s12">
                            <i class="material-icons prefix">assignment_ind</i>
                            <input type="text" id="member_id" readonly name="mbrid" value="${ memberVO.id }">
                            <label for="member_id">아이디</label>
                        </div>
                    </div>
                    <div class="row">
                        <div class="input-field col s12">
                            <i class="material-icons prefix">subtitles</i>
                            <input type="text" id="title" class="validate" name="title">
                            <label for="title">제목</label>
                        </div>
                    </div>
                    <div class="row">
                        <div class="input-field col s12">
                            <i class="material-icons prefix">subject</i>
                            <textarea id="textarea1" class="materialize-textarea" name="content"></textarea>
                            <label for="textarea1">내용</label>
                        </div>
                    </div>
                    
                    
                    <div class="row">
                    	<button type="button" class="btn-small waves-effect waves-light" id="btnAddFile">파일 추가</button>
                    </div>
                    
                    <div class="row" id="fileContainer">
                        <div class="file-field input-field col s12">
                            <div class="btn">
                                <span><i class="material-icons left">attach_file</i>첨부 파일</span>
                                <input type="file" name="files" multiple>
                            </div>
                            <div class="file-path-wrapper">
                                <input type="text" class="file-path validate">
                            </div>
                            <span class="helper-text">첨부파일로 업로드 가능한 용량은 최대 50MB 입니다.</span>
                        </div>
                    </div>


                    <div class="row center-align">
                        <div class="col s12 l8 offset-l2">
                            <div class="col s6">
                                <button type="submit" class="btn-large waves-effect waves-light">
                                    <i class="material-icons left">file_upload</i>
                                    새글 등록
                                </button>
                            </div>
                            <div class="col s6">
                                <a class="btn-large waves-effect waves-light" href="/board/list?pageNum=${ pageNum }">
                                    <i class="material-icons left">list</i>
                                    글목록
                                </a>
                            </div>
                        </div>
                    </div>

                    <div class="row">
                        <blockquote>
                            [새글 등록] 버튼을 눌러서 새 글을 등록해 보세요.<br>
                            새글쓰기를 하지 않고 글목록으로 가시려면 [글목록] 버튼을 누르세요.
                        </blockquote>
                    </div>
                </form>
            </div>
            <!-- end of Forms -->


        </div>
        <!-- end of Container -->

        
        <!-- Footer -->
        <%-- include footer.jsp --%>
 		<jsp:include page="/WEB-INF/views/include/footer.jsp" />
        <!-- end of Footer -->

    </div>
    <!-- end of App -->
    


    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
    <script>
        const sideNav = document.querySelector('.sidenav');
        M.Sidenav.init(sideNav, {});
    </script>
    <script>
    	var fileContainer = document.querySelector('#fileContainer');
    	
    	var btnAddFile = document.querySelector('#btnAddFile');
    	
    	var fileCount = 1; // 첨부파일 선택상자 개수
    	
    	btnAddFile.addEventListener('click', function () {
    		if (fileCount >= 5) {
    			alert('첨부파일은 최대 5개까지만 업로드 가능합니다.')
    			return;
    		}
    		fileCount++; // 추가된 첨부파일 선택상자 개수 반영
    		
    		var input = `
            <div class="file-field input-field col s12">
                <div class="btn">
                    <span><i class="material-icons left">attach_file</i>첨부 파일</span>
                    <input type="file" name="files" multiple>
                </div>
                <div class="file-path-wrapper">
                    <input type="text" class="file-path validate">
                </div>
                <span class="helper-text">첨부파일로 업로드 가능한 용량은 최대 50MB 입니다.</span>
            </div>
    		`;
    		
    		fileContainer.innerHTML += input;
    	});
    
    </script>
</body>

</html>

 

반응형