JSP 강의 Day06

주세환·2023년 4월 6일
0

JSP

목록 보기
6/16

게시글 작성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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' />
	<title>게시판 글쓰기</title>
	<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/bootstrap.min.css" />
	<!-- Include stylesheet -->
	<link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
</head>
<body>
    <div class="container">
        <div style="width:1500px; margin:0 auto; padding: 50px; border:1px solid #efefef;">
        	<h3>게시판 글쓰기</h3>
        	<hr />
            <div class="row">
                <div class="col-sm">
	                <div class="form-floating mb-2">
	                    <input type="text" id="title" class="form-control" autofocus required />
	                    <label for="title" class="form-label">제목</label>
	                </div>

                    <div style="margin-bottom:5px;">
                        <!-- Create the editor container -->
						<div id="editor" style="height:300px;">
						  <p>Hello World!</p>
						  <p>Some initial <strong>bold</strong> text</p>
						  <p><br></p>
						</div>
                    </div>
                    
                    <div class="form-floating mb-2">
                        <input type="text" id="writer" class="form-control" required />
                        <label for="writer" class="form-label">작성자</label>
                    </div>
	                <div>
                    	<input type="submit" value="글쓰기" class="btn btn-primary" onclick="getEditorContent()"/>
                    </div>
                </div>
            </div>
		</div>            
	</div>
	
	<!-- Include the Quill library -->
	<script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>
	
	<!-- Initialize Quill editor -->
	<script>
	
		const toolbarOptions = [
			  ['bold', 'italic', 'underline', 'strike'],        // toggled buttons
			  ['blockquote', 'code-block'],
	
			  [{ 'header': 1 }, { 'header': 2 }],               // custom button values
			  [{ 'list': 'ordered'}, { 'list': 'bullet' }],
			  [{ 'script': 'sub'}, { 'script': 'super' }],      // superscript/subscript
			  [{ 'indent': '-1'}, { 'indent': '+1' }],          // outdent/indent
			  [{ 'direction': 'rtl' }],                         // text direction
	
			  [{ 'size': ['small', false, 'large', 'huge'] }],  // custom dropdown
			  [{ 'header': [1, 2, 3, 4, 5, 6, false] }],
	
			  [{ 'color': [] }, { 'background': [] }],          // dropdown with defaults from theme
			  [{ 'font': [] }],
			  [{ 'align': [] }],
	
			  ['clean']                                         // remove formatting button
			];
		
		// 위쪽에 있는 태그 중에서 id가 editor인 것을 찾아서 toolbar는 toolbarOptions의 값으로 대체하고 테마를 snow로 해서 변경
		var quill = new Quill('#editor', {
			  modules: {
			    toolbar: toolbarOptions
			  },
			  theme: 'snow'
			});
		
		function getEditorContent(){
			const title 	= document.getElementById("title"); // id가 title인 정보를 가져오기
			const writer	= document.getElementById("writer"); // id가 writer인 정보를 가져오기
			const content 	= quill.root.innerHTML; // 위쪽의 editor객체를 통해서 가져오기
			
			// 유효성 검사
			if(title.value.length <= 0 ){
				alert('제목을 입력하세요.');
				title.focus();
				return false; // 아래쪽 소스코드를 수행하지 않음. 함수가 종료됨.
			}
			
			if(writer.value.length < 1){
				alert('작성자를 입력하세요.');
				title.focus();
				return false; // 함수 종료
			}
			
			// <form action="write.do" method="post">
				// <input type="text" name = "title" value = "실제입력값"></input>
				// <input type="text" name = "title" value = "실제입력값"></input>
				// <input type="text" name = "title" value = "실제입력값"></input>
			// </form>
			var form = document.createElement("form"); 
			form.action = "write.do";		
			form.method = "post";			
			
			// <input type"text" name = "title" value = "실제입력값"></input>
			var input1 = document.createElement("input");
			input1.type = "text"
			input1.name = "title";
			input1.value = title.value;
			form.appendChild(input1);
			
			var input2 = document.createElement("input");
			input1.type = "text"
			input1.name = "content";
			input1.value = content;
			form.appendChild(input2);
			
			var input3 = document.createElement("input");
			input1.type = "text"
			input1.name = "writer";
			input1.value = writer.value;
			form.appendChild(input3);
			
			document.body.appendChild(form);
			form.submit();
		}
	</script>
</body>
</html>

board_write.jsp를 이렇게 수정한다.

제목을 입력하지 않으니 제목을 입력하라는 창이 나온다.

작성자도 마찬가지이다.


public class Board {
	private long no;
	private String title;
	private String content;
	private String writer;
	private long hit;
	private Date regdate;
}

옛날에 사용하던 dto를 가져온다.


public interface BoardMapper {

	@Insert({
		" Insert Into board (title, content, writer)",
		" VALUES(#{obj.title}, #{obj.content}, #{obj.writer}) "
	})
	public int insertBoardOne(@Param("obj") Board obj);
}

BoardMapper에 insertBoardOne을 추가하고


protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		String title = request.getParameter("title");
		String content = request.getParameter("content");
		String writer = request.getParameter("writer");
		
		Board obj = new Board();
		obj.setTitle(title);
		obj.setContent(content);
		obj.setWriter(writer);
		
		int ret = MybatisContext.getSqlSession().getMapper(BoardMapper.class).insertBoardOne(obj);
		
		if(ret == 1) { // 성공하면 목록페이지로
			response.sendRedirect("select.do");
		}
		else { // 실패하면 글쓰기 페이지로
			response.sendRedirect("write.do");
		}
		
		// 1. DB 추가하기
		
		
		// 2. 적절한 페이지로 이동
		// http://127.0.0.1:8080/web02/board/select.do
		response.sendRedirect("select.do");
	}

BoardWriteController.java의 dopost를 이렇게 작성한다.


위 내용으로 글쓰기를 눌러보자.

아직 select.do를 만들지 않았으니 당연히 404 에러가 발생한다.

하지만 H2 콘솔에 들어가 확인해보면 데이터가 정상적으로 추가된 것을 볼 수 있다.


전체 개수

@Select({
	" SELECT b.* FROM board b ORDER BY no DESC"
})
public List<Board> selectBoardList();

mapper에 select를 생성하고

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	// 1.DB에서 게시글 전체 읽기
	List<Board> list = MybatisContext.getSqlSession().getMapper(BoardMapper.class).selectBoardList();
	
	// 2. view로 list전달
	request.setAttribute("list", list);
	
	// 3. board_select.jsp 화면에 표시
	request.getRequestDispatcher("/WEB-INF/board_write.jsp").forward(request, response);
	
}

BoardSelectController를 만든다.


<%@ 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">
<title>게시판 글쓰기</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/bootstrap.min.css" />
</head>
<body>
	<div class="container mx-auto p-2" style="width: 800px">
		<h2>게시글 목록</h2>
		<button type="button" class="btn btn-outline-primary">글쓰기</button>
		<form class="row g-2">
		<div class=""></div>
		</form>
		<table class="table">
	         <thead class="text-center">
	            <tr>
	               <th scope="col-1">#</th>
	               <th scope="col-4">제목</th>
	               <th scope="col-2">작성자</th>
	               <th scope="col-1">조회수</th>
	               <th scope="col-4">작성일자</th>
	            </tr>
	         </thead>
	         <tbody class="text-center">
            <c:forEach var="obj" items="${list}">
            <tr>
               <th scope="row">${obj.no}</th>
               <td>${obj.title}</td>
               <td>${obj.writer}</td>
               <td>${obj.hit}</td>
               <td>${obj.regdate}</td>
            </tr>
            </c:forEach>
         </tbody>
      </table>
	</div>      	
</body>
</html>

board_select.jsp를 생성하면

이렇게 목록이 나온다.

이것을

table

이라고 한다


// 전체 개수(페이지네이션용)
@Select({
	" SELECT COUNT(*) cnt FROM board"
})
public long countBoardList();

mapper를 생성하고

	// 게시글 전체 개수
		long cnt = MybatisContext.getSqlSession().getMapper(BoardMapper.class).countBoardList();
		
		// 2. view로 list전달
		request.setAttribute("pages", (cnt-1)/ 10 + 1);

controller에 추가한다.

jquery-3.6.4.min.js

jquery.twbsPagination.min.js

위 두 링크에 들어가서

이렇게 js 파일을 저장하고 js 폴더에 넣는다.

      </table>
      
       <ul id="pagination-demo" class="pagination-sm"></ul>
      
	</div>      	
	
	<script src="${pageContext.request.contextPath}/resources/js/jquery-3.6.4.min.js"></script>
	<script src="${pageContext.request.contextPath}/resources/js/jquery.twbsPagination.min.js"></script>
	<script>
	
	// $(document).ready"(function () {
	$(function(){
	    $('#pagination-demo').twbsPagination({
	        totalPages: Number('${pages}'),
	        visiblePages: 10,
	        first: '≪',
	    	last : '≫',
	    	prev : '<',
	    	next : '>',
	    	initiateStartPageClick:false,
	    	startPage : Number('${param.page}'),
	        onPageClick: function (event, page) {
	            window.location.href="select.do?page="+page;
	        }
	    });
	});
    </script>
	
</body>

board_select.jsp에 추가해준다.

이렇게 전체 로딩이 되면서 아래에 페이지 넘어갈 수 있는 버튼이 생긴다.

이 버튼을

pagination-demo

라고 한다.

+startPage : Number('${param.page}')이 있기 때문에 주소창 맨 뒤에 ?page=1이 들어가야 한다.

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		// 주소창에 ?page가 없을 경우 처리
		String page = request.getParameter("page");
		if( page ==null ) {
			response.sendRedirect("select.do?page=1"); // 강제로 page=1
			return; // 메소드 종료시키기
		}

BoardSelectController.java의 doGet에 위 코드를 추가해주자.

엔터를 누르면

자동으로 page=1로 이동한다.


// 페이지네이션
@Select({
	" SELECT b.* FROM ( " ,
		" SELECT b.*, ROW_NUMBER() OVER (ORDER BY no DESC) rown FROM board b " ,
	" ) b WHERE rown >= #{start} AND rown <=#{end} ORDER BY no DESC "
})
public List<Board> selectBoardListPage(@Param("start") int start, @Param("end") int end);

mapper에 페이지네이션 매퍼를 추가하였다.

// 페이지네이션 시작값
		int start = Integer.parseInt(page)*10-9;
		// 페이지네이션 종료값
		int end = Integer.parseInt(page)*10;
		
		// 1.DB에서 게시글 전체 읽기
		List<Board> list = MybatisContext.getSqlSession().getMapper(BoardMapper.class).selectBoardListPage(start,end);

BoardSelectController의 doGet을 수정하였다.

한 페이지에 10개까지만 나오고, 총 글 수가 36이니 4페이지까지만 생성된다.

완성 코드

BoardMapper.java

package mapper;

import java.util.List;

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import dto.Board;

@Mapper
public interface BoardMapper {

	// 글쓰기
	@Insert({
		" Insert Into board (title, content, writer)",
		" VALUES(#{obj.title}, #{obj.content}, #{obj.writer}) "
	})
	public int insertBoardOne(@Param("obj") Board obj);
	
	// 전체 목록
	@Select({
		" SELECT b.* FROM board b ORDER BY no DESC"
	})
	public List<Board> selectBoardList();
	
	// 전체 개수(페이지네이션용)
	@Select({
		" SELECT COUNT(*) cnt FROM board "
	})
	public long countBoardList();
	
	// 페이지네이션
	@Select({
		" SELECT b.* FROM ( " ,
			" SELECT b.*, ROW_NUMBER() OVER (ORDER BY no DESC) rown FROM board b " ,
		" ) b WHERE rown >= #{start} AND rown <=#{end} ORDER BY no DESC "
	})
	public List<Board> selectBoardListPage(@Param("start") int start, @Param("end") int end);
}

BoardSelectController.java

package controller;

import java.io.IOException;
import java.util.List;

import config.MybatisContext;
import dto.Board;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import mapper.BoardMapper;

@WebServlet(urlPatterns = {"/board/select.do"})
public class BoardSelectController extends HttpServlet {
	private static final long serialVersionUID = 1L;

    public BoardSelectController() {
        super();
    }
    
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		// 주소창에 ?page가 없을 경우 처리
		String page = request.getParameter("page");
		if( page ==null ) {
			response.sendRedirect("select.do?page=1"); // 강제로 page=1
			return; // 메소드 종료시키기
		}
		// 페이지네이션 시작값
		int start = Integer.parseInt(page)*10-9;
		// 페이지네이션 종료값
		int end = Integer.parseInt(page)*10;
		
		// 1.DB에서 게시글 전체 읽기
		List<Board> list = MybatisContext.getSqlSession().getMapper(BoardMapper.class).selectBoardListPage(start,end);
		
		// 게시글 전체 개수
		long cnt = MybatisContext.getSqlSession().getMapper(BoardMapper.class).countBoardList();
		
		// 2. view로 list전달
		request.setAttribute("list", list);
		request.setAttribute("pages", (cnt-1)/ 10 + 1);
		
		// 3. board_select.jsp 화면에 표시
		request.getRequestDispatcher("/WEB-INF/board_select.jsp").forward(request, response);
		
	}


	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
	}

}

board_select.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>
<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>게시판글쓰기</title>
    <link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/bootstrap.min.css" /><title>Insert title here</title>
</head>

<body>
	<div class="container">
		<a href="write.do" class="btn btn-primary">글쓰기</a>
		
		<div style="width:500px; margin-top:10px;">
			<form class="row g-2">
  				<div class="col-auto">
					<input type="text" name="text" class="form-control" placeholder="검색어" style="width:300px;"/>
				</div>
				<div class="col-auto">
					<input type="submit" class="btn btn-primary" value="검색" />
				</div>
			</form>		
		</div>
		
		<table class="table table-hover">
  			<thead>
    			<tr>
					<th scope="col">글번호</th>
					<th scope="col">제목</th>
					<th scope="col">작성자</th>
					<th scope="col">조회수</th>
					<th scope="col">날짜</th>
			    </tr>
  			</thead>
			<tbody>
				<c:forEach var="obj" items="${list}">
				<tr>
					<td scope="row">${obj.no}</td>
					<td>${obj.title}</td>
					<td>${obj.writer}</td>
					<td>${obj.hit}</td>
					<td>${obj.regdate}</td>
				</tr>
				</c:forEach>
			</tbody>
		</table>
		
		<ul id="pagination-demo" class="pagination"></ul>
	</div>
	
	<script src="${pageContext.request.contextPath}/resources/js/jquery-3.6.4.min.js"></script>
	<script src="${pageContext.request.contextPath}/resources/js/jquery.twbsPagination.min.js"></script>
	<script>
	// $(document).ready(function(){
	$(function(){
		$('#pagination-demo').twbsPagination({
			  totalPages	: Number('${pages}'),
			  visiblePages	: 10,
			  first 		: '≪',
			  last 			: '≫',
			  prev 			: '<',
			  next 			: '>',
			  initiateStartPageClick : false,
			  startPage  	: Number('${param.page}'),	
			  onPageClick	: function (event, page) {
					window.location.href="select.do?page=" + page;
			  }
		});	
	});
	</script>

</body>
</html>```

0개의 댓글