Back-End/Java

[Spring] Legacy Project 게시판 글쓰기 구현하기

CJun 2021. 6. 15. 00:25
반응형
로그인 안하면 글쓰기를 할 수 없게 만듬

 

boardList.jsp

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

<!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="index.html" class="breadcrumb">홈</a> <a href="boardList.html" class="breadcrumb">게시판 글목록</a>
					</div>
				</div>
			</nav>
			<!-- end of Breadcrumbs -->


			<div class="row">
				<h4 class="center-align">게시판 글목록</h4>
				<hr style="margin-bottom: 50px;">
			</div>

			<c:if test="${ not empty memberVO }">
				<div class="row">
					<a href="/board/write?pageNum=${ pageMaker.cri.pageNum }" class="waves-effect waves-light btn right">
					<i class="material-icons left">create</i>새글쓰기
					</a>
				</div>

			</c:if>

			<div class="row">
				<!-- Table -->
				<table class="highlight responsive-table ">
					<thead class="blue white-text">
						<tr>
							<th class="center-align">번호</th>
							<th class="center-align">글제목</th>
							<th class="center-align">글쓴이</th>
							<th class="center-align">작성일</th>
							<th class="center-align">조회수</th>
						</tr>
					</thead>

					<tbody>
						<c:choose>
							<c:when test="${ pageMaker.total gt 0 }">

								<%-- pageScope → requestScope → sessionScope → applicationScope --%>
								<c:forEach var="board" items="${ boardList }">
									<tr onclick="location.href='/board/content?num=${ board.num }&pageNum=${ pageMaker.cri.pageNum }'" style="cursor: pointer;">
										<td class="center-align">${ board.num }</td>
										<td>${ board.title }</td>
										<td class="center-align">${ board.mbrid }</td>
										<td class="center-align"><fmt:formatDate value="${ board.regDate }" pattern="yyyy.MM.dd" /></td>
										<td class="center-align">${ board.readcount }</td>
									</tr>
								</c:forEach>

							</c:when>
							<c:otherwise>
								<tr>
									<td colspan="5">게시판 글이 없습니다.</td>
								</tr>
							</c:otherwise>
						</c:choose>
					</tbody>
				</table>
				<!-- end of Table -->
			</div>


			<div class="row center">
				<!-- Pagination -->
				<ul class="pagination">
					<li class="${ pageMaker.prev ? 'waves-effect' : 'disabled' }"><a id="prev"><i class="material-icons">chevron_left</i></a></li>

					<c:forEach var="i" begin="${ pageMaker.startPage }" end="${ pageMaker.endPage }" step="1">
						<li class="${ pageMaker.cri.pageNum == i ? 'active' : 'waves-effect' }"><a href="/board/list?pageNum=${ i }">${ i }</a></li>
					</c:forEach>

					<li class="${ pageMaker.next ? 'waves-effect' : 'disabled' }"><a id="next"><i class="material-icons">chevron_right</i></a></li>
				</ul>
				<!-- end of Pagination -->
			</div>


			<div class="row">
				<form action="">
					<!-- AutoComplete -->
					<div class="col s12 l6 offset-l3">
						<div class="input-field">
							<i class="material-icons prefix">find_in_page</i> <input type="text" id="autocomplete-input" class="autocomplete"> <label for="autocomplete-input">검색</label>
						</div>
					</div>
					<!-- end of AutoComplete -->
				</form>
			</div>



		</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, {});

		const ac = document.querySelector('.autocomplete');
		M.Autocomplete.init(ac, {
			data : {
				'파리' : null,
				'베네치아' : null,
				'암스테르담' : null,
				'부다페스트' : null,
				'프랑크푸르트' : null,
				'비엔나' : null,
				'드라스덴' : null,
				'프라하' : null,
				'로마' : null
			}
		});
	</script>
	<script>
		// [이전] a태그 클릭이벤트
		var prev = document.querySelector('a#prev');

		prev.addEventListener('click', function(event) {
			event.preventDefault();

			var isPrev = $
			{
				pageMaker.prev
			}
			;
			if (!isPrev) {
				return;
			}
			location.href = '/board/list?pageNum=${ pageMaker.startPage - 1 }';
		});

		// [다음] a태그 클릭이벤트
		var next = document.querySelector('a#next');

		next.addEventListener('click', function(event) {
			event.preventDefault();

			var isNext = $
			{
				pageMaker.next
			}
			;
			if (!isNext) {
				return;
			}
			location.href = '/board/list?pageNum=${ pageMaker.endPage + 1 }';
		});
	</script>
</body>

</html>

 

boardContent.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<!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/content?num=${ boardVO.num }&pageNum=${ pageNum }" class="breadcrumb">게시판 글내용</a>
                    </div>
                </div>
            </nav>
            <!-- end of Breadcrumbs -->


            
            <div class="row">
                <h4 class="center-align">게시판 글내용</h4>
                <hr style="margin-bottom: 50px;">
            </div>

            <div class="row">
                <div class="col s12 l8 offset-l2">
                    <div class="card">
                        <div class="card-image">
                            <img src="/resources/images/praha.jpg">
                        </div>
                        <div class="card-content">
                            <span class="card-title">${ boardVO.title }</span>
                            <div class="row">
                            	<div class = "col s12 14">
                            		조회수: ${ boardVO.readcount }
                            	</div>
                            	
                            	<div class = "col s12 14">
                            		글쓴이: ${ boardVO.mbrid}
                            	</div>
                            	
                            	<div class = "col s12 14">
                            		작성일자: <fmt:formatDate value="${ boardVO.regDate }" pattern="yyyy.MM.dd a hh:mm:ss"/>
                            	</div>
                            </div>
                            <pre>${ boardVO.content }</pre>
                        </div>
                        <div class="card-action">
                            <a href="#!">첨부파일1</a>
                            <a href="#!">첨부파일2</a>
                            <a href="#!">첨부파일3</a>
                        </div>
                    </div>
                </div>
            </div>
            

            <div class="row center-align">
                <div class="col s12 l8 offset-l2">
                    <div class="col s6 m3">
                        <a class="btn-large waves-effect waves-light">
                            <i class="material-icons left">edit</i>
                            글수정
                        </a>
                    </div>
                    <div class="col s6 m3">
                        <a class="btn-large waves-effect waves-light">
                            <i class="material-icons left">delete</i>
                            글삭제
                        </a>
                    </div>
                    <div class="col s6 m3">
                        <a class="btn-large waves-effect waves-light">
                            <i class="material-icons left">reply</i>
                            답글쓰기
                        </a>
                    </div>
                    <div class="col s6 m3">
                        <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">
                <div class="col s12 l8 offset-l2">
                    <blockquote>
                        [글수정] 버튼을 눌러서 현재 글을 수정할 수 있어요.<br>
                        [글삭제] 버튼을 눌러서 현재 글을 삭제할 수 있어요.<br>
                        [답글쓰기] 버튼을 눌러서 현재 글에 대한 답글을 등록할 수 있어요.<br>
                        글목록으로 가시려면 [글목록] 버튼을 누르세요.
                    </blockquote>
                </div>
            </div>


        </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>
</body>

</html>

 

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">
                	<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">
                        <div class="file-field input-field col s12">
                            <div class="btn">
                                <span><i class="material-icons left">attach_file</i>첨부 파일</span>
                                <input type="file" 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>
</body>

</html>

 

BoardController.java

@GetMapping("/content")
	public String content(int num, @ModelAttribute("pageNum") String pageNum, Model model) {
		
		// 조회수 1 증가시키기
		boardService.modifyReadcount(num);
		
		// 글 한개 가져오기
		BoardVO boardVO = boardService.getBoard(num);
		
		model.addAttribute("boardVO", boardVO);
		// model.addAttribute("pageNum", pageNum);
		
		return "board/boardContent";
		
	} // content
	
	// 주 글쓰기 요청
	@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) {
		
		// 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
		
		// 주 글을 테이블에 insert하기
		boardService.register(boardVO);
		
		// 리다이렉트 시 서버로 다시 전달할 데이터를 저장하기
		rttr.addAttribute("num", boardVO.getNum());
		rttr.addAttribute("pageNum", pageNum);
		
		return "redirect:/board/content";
	} // write post

반응형