본문 바로가기
인천일보아카데미/- 학습일지

[학습일지]JAVA교육일지 게시판CRUD 4⭐검색기능(1)

by w1z 2022. 7. 20.

기본 게시판 만들기

  6. 게시판 글 내용 자세히 확인하기

  7. 게시판 글 내용 수정하기

  8. 게시판 글 내용 삭제하기


기본 게시판 만들기

6. 게시판 글 내용 자세히 확인하기

[ 글 내용 상세보기 구현 목표 ]

- 글 내용에는 태그 적용 유무가 있으므로, 태그를 이용해서 악용방지를 위한 <script> 사전 차단하기

- 글 내용 페이지에 들어올 때마다 조회수 1 증가 ( 새로고침(F5) 연속으로 증가못하게 구현 )

 

[ DB 작업 ]

1) com.test.myapp.board > BoardDAO.java

- DB 작업 > DAO 위임 > select where seq = ?

- 조회수 증가 > 미리 만들어둔 readcount 컬럼 사용

*기존 BoardDAO.java 파일에 해당 메소드만 추가하면 된다.

// View 서블릿이 글번호를 줄테니 레코드 내용 전부를 DTO에 담아서 돌려주세요!
public BoardDTO get(String seq) {
	
	try {
		
		String sql = "select b.*, (select name from tblUsers where id = b.id ) as name "
				+ "from tblBoards b where seq=?";
		
		pstat = conn.prepareStatement(sql);
		pstat.setString(1, seq);
		
		rs = pstat.executeQuery();
		
		if ( rs.next() ) {
			
			BoardDTO dto = new BoardDTO();
			
			dto.setSeq(rs.getString("seq"));
			dto.setSubject(rs.getString("subject"));
			dto.setContent(rs.getString("content"));
			dto.setId(rs.getString("id"));
			dto.setName(rs.getString("name"));
			dto.setReadcount(rs.getString("readcount"));
			dto.setRegdate(rs.getString("regdate"));
			dto.setTag(rs.getString("tag"));
			
			return dto;
		}
		
	} catch (Exception e) {
		e.printStackTrace();
	}
	
	return null;
}

// View 서블릿이 글번호를 줄테니 조회수를 +1 해주세요!
public void updateReadCount(String seq) {
	
	try {
		
		String sql = "update tblBoards set readcount = readcount + 1 where seq=?";
		
		pstat = conn.prepareStatement(sql);
		pstat.setString(1, seq);
		
		pstat.executeUpdate();
		
	} catch (Exception e) {
		e.printStackTrace();
	}
	
}

 

[ Servlet + JSP 작업 ]

1) com.test.myapp.board > View.java

- 데이터 가져오기 ( seq )

- DB작업 ( select where seq = ? )

- BoardDTO 반환하기 >  JSP 호출 + 전달하기

@WebServlet("/board/view.do")
public class View extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		
		
		// 1. 데이터 가져오기(seq)
		String seq = req.getParameter("seq");
		
		// 2. DB 작업 > DAO 위임 > select where seq
		BoardDAO dao = new BoardDAO();
		
		// 2.3 조회수 증가하기
		HttpSession session = req.getSession();
		if (session.getAttribute("read") != null & session.getAttribute("read").toString().equals("n")) {
			dao.updateReadCount(seq);
			session.setAttribute("read", "y");
		}
		
		BoardDTO dto = dao.get(seq);
		
		// 2.5 글 내용 ( 태그를 이용해서 악용하는 사람들 방지를 위한 코드 )
		String subject = dto.getSubject();
		String content = dto.getContent();
		
		// 무조건 글 제목과 내용에 들어있는 <script>태그는 비활성화 시키기!!
		subject = subject.replace("<script", "&lt;script").replace("</script>", "&lt;/script&gt;");
		dto.setSubject(subject);
		
		content = content.replace("<script", "&lt;script").replace("</script>", "&lt;/script&gt;");
		dto.setContent(content);

		// 글 내용에 태그 적용 안되게 하기
		if (dto.getTag().equals("n")) {
			// <b> -> &lt;b&gt; -> 꺽새 제거하기
			content = content.replace("<", "&lt;").replace(">", "&gt;");
			dto.setContent(content);
		}
		
		// 글 내용(content)에 개행 문자 처리하기
		content = content.replace("\r\n", "<br>");
		dto.setContent(content);
		
		
		// 3. BoardDTO 반환 > JSP 호출하기 + 전달하기
		req.setAttribute("dto", dto);

		RequestDispatcher dispatcher = req.getRequestDispatcher("/WEB-INF/views/board/view.jsp");
		dispatcher.forward(req, resp);

	}
}

 

2) WEB-INF > views > board > view.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">
<title>myapp</title>
<%@ include file="/inc/asset.jsp" %>
<style>
	.main-section .table th { width: 120px; }
	.main-section .table td { width: 280px; text-align: left; }
	.main-section .table tr:nth-child(4) td { height: 300px; }
</style>
</head>
<body>
	<!-- view.jsp -->
	<%@ include file="/inc/header.jsp" %>
	
	<section class="main-section">
		
		<h1>Board <small>View</small></h1>
		
		<table class="table table-bordered">
			<tr>
				<th>번호</th>
				<td>${ dto.seq }</td>
				<th>이름</th>
				<td>${ dto.name }(${ dto.id })</td>
			</tr>
			<tr>
				<th>날짜</th>
				<td>${ dto.regdate }</td>
				<th>읽음</th>
				<td>${ dto.readcount }</td>
			</tr>	
			<tr>
				<th>제목</th>
				<td colspan="3">${ dto.subject }</td>
			</tr>		
			<tr>
				<th>내용</th>
				<td colspan="3">${ dto.content }</td>
			</tr>		
		</table>
		
		<div class="btns">
		
			<button type="button" class="btn btn-primary"
				onclick="location.href='/myapp/board/edit.do?seq=${ dto.seq }';">수정하기</button>
				
			<button type="button" class="btn btn-primary"
				onclick="location.href='/myapp/board/del.do?seq=${ dto.seq }';">삭제하기</button>

			<button type="button" class="btn btn-default"
				onclick="location.href='/myapp/board/list.do';">돌아가기</button>
				
		</div>

	</section>	

	<%@ include file="/inc/init.jsp" %>
</body>
</html>

 

- 글 내용 상세 페이지 ( http://localhost:8090/myapp/board/view.do?seq=21 )

해당 글 내용과 조회수(읽음)가 늘어난걸 볼 수 있다.

 

 

7. 게시판 글 내용 수정하기

[ 구현 목표 ]

- 상세 페이지(view.do)에서 수정하기 버튼 클릭 시 해당 내용, 제목, 태그가 그대로 작성되어 있는 상태로 수정한다.

- 수정 완료 후, 바로 게시판 목록 페이지로 가는것이 아닌, 상세 페이지(view.do)로 다시 이동해서 수정된 내용을 확인 할 수 있도록 한다.

 

[ Servlet + JSP 작업 - 수정하기 페이지 이동하기 ]

1) com.test.myapp.board > Edit.java

- 데이터 가져오기 ( seq )

- DB 작업 ( update )

- BoardDTO 반환 > JSP 호출, 전달 하기

@WebServlet("/board/edit.do")
public class Edit extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {		
		
		// 1. 데이터 가져오기(seq)
		String seq = req.getParameter("seq");
		
		// 2. DB 작업 > DAO 위임 > select where seq
		BoardDAO dao = new BoardDAO();
		
		BoardDTO dto = dao.get(seq);
		
		// 3. BoardDTO 반환 > JSP 호출하기 + 전달하기
		req.setAttribute("dto", dto);

		RequestDispatcher dispatcher = req.getRequestDispatcher("/WEB-INF/views/board/edit.jsp");
		dispatcher.forward(req, resp);

	}

}

 

2) WEB-INF > views > board > edit.jsp

- 해당 작성자가 글쓰기한 제목, 내용, 태그유무가 그대로 남아있다.

- 히든태그를 이용해서 해당 글번호인 seq 를 넘겨준다.

- 수정하기 버튼 클릭 시 form 태그의 method="POST"로 editok.do 페이지로 이동한다.

<%@ 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">
<title>myapp</title>
<%@ include file="/inc/asset.jsp" %>
<style>
	.table th { width: 120px; }
	.table td { width: 680px; }
	
	.table #content { height: 300px; }
</style>
</head>
<body>
	<!-- edit.jsp -->
	<%@ include file="/inc/header.jsp" %>
	
	<section class="main-section">
		
		<h1>Board <small>Edit</small></h1>
		
		<form method="POST" action="/myapp/board/editok.do">
			<table class="table table-bordered">
				<tr>
					<th>제목</th>
					<td><input type="text" name="subject" id="subject" class='form-control' required value="${ dto.subject }"/></td>
				</tr>		
				<tr>
					<th>내용</th>
					<td>
						<textarea name="content" id="content" class="form-control" required >${ dto.content }</textarea>
					</td>
				</tr>		
				<tr>
					<th>태그</th>
					<td>
						<select name="tag" id="tag" class="form-control short">
							<option value="n">적용안함</option>
							<option value="y">적용함</option>
						</select>
					</td>
				</tr>		
			</table>
			
			<div class="btns">
				<button type="submit" class="btn btn-primary">수정하기</button>
				<button type="button" class="btn btn-default"
					onclick="location.href='/myapp/board/list.do';">돌아가기</button>
			</div>
			
			<!-- 잊지말고 히든태그로 seq 넘겨주기 -->
			<input type="hidden" name="seq" value="${ dto.seq }"/>
		</form>

	</section>	
	
	<%@ include file="/inc/init.jsp" %>
	<script>
		${'#tag'}.val('${ dto.tag }');
	</script>
</body>
</html>

 

[ DB 작업 ]

1) com.test.myapp.board > BoardDAO.java

- DB작업 > DAO 위임 > select where seq = ?

*기존 BoardDAO.java 파일에 해당 메소드만 추가하면 된다.

// EditOk 서블릿이 수정할 DTO를 줄테니 update 해주세요!
public int edit(BoardDTO dto) {
	
	try {
		
		String sql = "update tblBoards set subject=?, content=?, tag=? where seq=?";
		
		pstat = conn.prepareStatement(sql);
		
		pstat.setString(1, dto.getSubject());
		pstat.setString(2, dto.getContent());
		pstat.setString(3, dto.getTag());
		pstat.setString(4, dto.getSeq());
		
		return pstat.executeUpdate(); // 성공시 1 실패시 0
		
	} catch (Exception e) {
		e.printStackTrace();
	}
	
	return 0;
}

 

[ Servlet 작업 - 수정 완료 후 처리하기 ]

1) com.test.myapp.board > EditOk.java

- 데이터 가져오기 ( seq, subject, content, tag )

- DB 작업

- 결과 후 처리

@WebServlet("/board/editok.do")
public class EditOk extends HttpServlet {

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		// 1. 데이터 가져오기
		String seq = req.getParameter("seq");
		String subject = req.getParameter("subject");
		String content = req.getParameter("content");
		String tag = req.getParameter("tag");
		
		// 2. DB 작업 > DAO 위임 > update
		BoardDAO dao = new BoardDAO();
		BoardDTO dto = new BoardDTO();
		
		dto.setSeq(seq);
		dto.setSubject(subject);
		dto.setContent(content);
		dto.setTag(tag);
		
		int result = dao.edit(dto);
		
		// 3. 결과 후 처리
		// 수정할 글번호(seq) 가지고 넘어가기
		if ( result == 1 ) {
			resp.sendRedirect("/myapp/board/view.do?seq=" + seq);
		} else {
			resp.sendRedirect("/myapp/board/edit.do?seq=" + seq);
		}

	}

}

 

- 수정하기 페이지 ( http://localhost:8090/myapp/board/edit.do?seq=21 )

- 수정하기 페이지 ( http://localhost:8090/myapp/board/edit.do?seq=21 )

해당 글 번호(seq)를 가지고 수정하기 페이지로 이동한 모습이다.

 

- 수정하기 버튼 클릭 후 수정된 페이지 ( http://localhost:8090/myapp/board/view.do?seq=21 )

수정 완료 후, 바로 게시판 목록으로 넘어가는것이 아닌 상세보기 페이지(view.do)로 이동한다.

 

8. 게시판 글 내용 삭제하기

[ 구현 목표 ]

- 상세 페이지(view.do)에서 삭제하기 버튼 클릭 시 되묻는 경고 페이지로 이동한다.

- 삭제 완료 후, 삭제 된지 확인할 수 있는 게시판 목록 페이지(list.do)로 이동한다.

 

[ Servlet + JSP 작업 - 삭제하기 페이지 이동하기 ]

1) com.test.myapp.board > Del.java

- 데이터 가져오기 ( seq )

- JSP 호출하기 + 글번호 ( seq ) 전달하기

@WebServlet("/board/del.do")
public class Del extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		// 1. 데이터 가져오기(seq)
		String seq = req.getParameter("seq");
		
		// 2. JSP 호출하기 + 글번호(seq) 전달하기
		req.setAttribute("seq", seq);
		
		RequestDispatcher dispatcher = req.getRequestDispatcher("/WEB-INF/views/board/del.jsp");
		dispatcher.forward(req, resp);
	}
}

 

2) WEB-INF > views > board > del.jsp

- 몇번 게시물인지 번호를 확인할 수 있다.

- 실수로 삭제페이지로 이동 방지를 위한, 한번 더 묻는 삭제하기, 돌아가기 버튼이 있다.

- 히든태그를 이용해서 해당 글번호인 seq 를 넘겨준다.

- 삭제하기 버튼 클릭 시 form 태그의 method="POST"로 delok.do 페이지로 이동한다.

<%@ 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">
<title>myapp</title>
<%@ include file="/inc/asset.jsp" %>
<style>
	.main-section .table th { width: 120px; }
	.main-section .table td { width: 680px; text-align: left; }
	
	.table #content { height: 300px; }
</style>
</head>
<body>
	<!-- del.jsp -->
	<%@ include file="/inc/header.jsp" %>
	
	<section class="main-section">
		
		<h1>Board <small>Del</small></h1>
		
		<form method="POST" action="/myapp/board/delok.do">
			<table class="table table-bordered">
				<tr>
					<th>번호</th>
					<td>${ seq }번 게시물을 삭제합니다.</td>
				</tr>		
			</table>
			
			<div class="btns">
				<button type="submit" class="btn btn-danger">삭제하기</button>
				<button type="button" class="btn btn-default"
					onclick="location.href='/myapp/board/view.do?seq=${ seq }';">돌아가기</button>
			</div>
			
			<input type="hidden" name="seq" value="${ seq }" />
		</form>

	</section>	
	
	<%@ include file="/inc/init.jsp" %>
</body>
</html>

 

[ DB 작업 ]

- DB작업 > DAO 위임 > delete where seq = ?

*기존 BoardDAO.java 파일에 해당 메소드만 추가하면 된다.

// DelOk 서블릿이 글번호를 줄테니 글을 삭제해주세요!
public int del(String seq) {
	
	try {
		
		String sql = "delete from tblBoards where seq=?";

		pstat = conn.prepareStatement(sql);
		pstat.setString(1, seq);
		
		return pstat.executeUpdate(); // 성공시 1 실패시 0
		
	} catch (Exception e) {
		e.printStackTrace();
	}
	
	return 0;
}

 

[ Servlet 작업 - 삭제 완료 후 처리하기 ]

- 데이터 가져오기 ( seq )

- DB 작업 ( delete )

- 결과 후 처리

@WebServlet("/board/delok.do")
public class DelOk extends HttpServlet {

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		// 1. 데이터 가져오기(seq)
		String seq = req.getParameter("seq");
		
		// 2. DB 작업 > DAO 위임 > delete
		BoardDAO dao = new BoardDAO();
		
		HttpSession session = req.getSession();
		
		int result = dao.del(seq);
		
		// 3. 결과 후 처리
		// 수정할 글번호(seq) 가지고 넘어가기
		if ( result == 1 ) {
			resp.sendRedirect("/myapp/board/list.do");
		} else {
			resp.sendRedirect("/myapp/board/del.do?seq=" + seq);
		}

	}
}

 

- 삭제하기 페이지 ( http://localhost:8090/myapp/board/del.do?seq=21 )

해당 글번호(seq)를 가지고 경고표시 용도인 삭제페이지로 이동한 모습이다.

 

- 삭제하기 버튼 클릭 후 게시판 목록 페이지 ( http://localhost:8090/myapp/board/list.do )

삭제하기를 누르면 DB에서 delete 되며 게시판 목록으로 이동한다. ( 해당 글번호=21 내용이 삭제된 모습이다. )


MEMO>

# 자바 배포파일(압축파일)
  1. java class -> *.jar
  2. web application -> *.war

# DAO, DTO는 업무별로 따로따로 만든다. ( MemberDAO, BoardDAO ... )

# 오늘 처음으로 게시판을 구현해봤는데, 처음부터 전부 구현하려 하지말고, 단계별로 확장해 나가자.

# form태그에서 POST로 받을시 서블릿으로 doPost로 받게 되는데, 깨짐 현상을 위해 setCharacterEncoding("UTF-8")을 쓰게 되는데... 매번 쓰기 불편하다. 아래 2가지를 하면 해당 메소드를 안써도 된다.
    --> 1. EncodingFilter 클래스를 따로 만들어서 구현 가능하다.
    --> 2. xml파일에 필터를 적용

# 페이지 이동 시, 그냥 넘어가는 페이지가 있으며 페이지가 가지고 있는 내용(seq, content등..)을 갖고 가는 경우를 잘 구별해야한다!!