JSP
12.01.(목) JSP(12): 게시판 만들기(1)
콜라든포비
2022. 12. 5. 23:23
게시판 홈페이지
게시판이란 작성자가 있고, 회원들만 글을 작성할 수 있어야 한다.
게시판 작성할때 아이디를 입력하고 글을 작성하는데, 작성자 아이디가 DB에 없을 경우, 글을 못 쓰는 구조로 만들 것이다.
우선 게시판 목록페이지를 만들어보자.
DAO, DTO, VO
DAO(Data Access Object)란 DB의 데이터에 접근하기 위한 객체이다.
DB에 접근하기 위한 로직과 비지니스 로직을 분리하기 위해서 사용한다.
DTO(Data Transfer Object)는 계층 간 데이터 교환을 하기 위해 사용하는 객체로, 로직을 가지지않는 순수한 데이터 객체이다.
getter와 setter로 구성된다.
VO(Value Object)는 값 오브젝트로써 read-only특징을 지닌다. 그에 반해 DTO는 setter를 통해 값을 변경할 수 있다.
DTO에서 사용할 변수들을 선언해주고, 우클릭-Source-Generate Getters and Setters...를 누르면 자동으로 생성해준다.
package com.multi.app.board;
/*
* VO : Value Object, DTO : Data Transfer Object
* 게시판 구현에 필요한 변수들을 캡슐화하여 작성하는 클래스
*/
public class BoardDTO {
private int postno;
private String subject;
private String content;
private String username;
private int hitcount;
private String ipAddr;
private String regdate;
public int getPostno() {
return postno;
}
public void setPostno(int postno) {
this.postno = postno;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getHitcount() {
return hitcount;
}
public void setHitcount(int hitcount) {
this.hitcount = hitcount;
}
public String getIpAddr() {
return ipAddr;
}
public void setIpAddr(String ipAddr) {
this.ipAddr = ipAddr;
}
public String getRegdate() {
return regdate;
}
public void setRegdate(String regdate) {
this.regdate = regdate;
}
}
이 DTO를 활용하여 우리 게시판에 필요한 DAO를 설계해보자.
package com.multi.app.board;
import java.util.ArrayList;
import java.util.List;
import com.multi.app.DBConn;
public class BoardDAO extends DBConn{
// 목록 선택 : board_tbl을 전체 선택해서 DTO에 데이터를 set하고,
// DTO에서 컬렉션(List)로 리턴한다
public List<BoardDTO> boardListAll() {
List<BoardDTO> list = new ArrayList<BoardDTO>();
try {
dbConn();
sql = "SELECT postno, subject, username, hitcount, to_char(regdate, 'mm-dd HH:MI')\n"
+ "FROM board_tbl ORDER BY postno DESC";
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
while(rs.next()) {
BoardDTO dto = new BoardDTO();
dto.setPostno(rs.getInt(1));
dto.setSubject(rs.getString(2));
dto.setUsername(rs.getString(3));
dto.setHitcount(rs.getInt(4));
dto.setRegdate(rs.getString(5));
list.add(dto);
}
}catch(Exception e) {
e.printStackTrace();
}finally {
dbClose();
}
return list;
}
// 글 내용보기, 글 수정
public BoardDTO boardSelectOne(int postno, int part) {
BoardDTO dto = new BoardDTO();
try {
// 조회수 증가
// part -> 1 : 글 내용 보기, 2 : 글 수정
if(part==1) hitCount(postno);
// 글 선택
dbConn();
sql = "select postno, username, subject, content, hitcount, regdate "
+ "from board_tbl where postno=?";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, postno);
rs = pstmt.executeQuery();
// DTO에 담아서 리턴
if(rs.next()) {
dto.setPostno(rs.getInt(1));
dto.setUsername(rs.getString(2));
dto.setSubject(rs.getString(3));
dto.setContent(rs.getString(4));
dto.setHitcount(rs.getInt(5));
dto.setRegdate(rs.getString(6));
}
}catch(Exception e) {
e.printStackTrace();
}finally {
dbClose();
}
return dto;
}
// 조회수 증가
public void hitCount(int postno) {
try {
dbConn();
sql = "update board_tbl set hitcount=hitcount+1 where postno=?";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, postno);
pstmt.executeUpdate();
}catch(Exception e) {
e.printStackTrace();
}finally {
dbClose();
}
}
// 글 등록
public int boardPost(BoardDTO dto) {
int result = 0;
try {
dbConn();
sql = "INSERT INTO BOARD_TBL(postno, subject, content, username, ipAddr) VALUES (board_seq.nextval,?,?,?,?)";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, dto.getSubject());
pstmt.setString(2, dto.getContent());
pstmt.setString(3, dto.getUsername());
pstmt.setString(4, dto.getIpAddr());
result = pstmt.executeUpdate(); // 수정된 데이터 개수
}catch(Exception e){
e.printStackTrace();
}finally {
dbClose();
}
return result;
}
// 글 수정
public int boardEdit(BoardDTO dto) {
int result = 0;
try {
dbConn();
sql = "UPDATE board_tbl SET subject=?, content=? WHERE postno=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, dto.getSubject());
pstmt.setString(2, dto.getContent());
pstmt.setInt(3, dto.getPostno());
result = pstmt.executeUpdate();
}catch(Exception e) {
e.printStackTrace();
}finally {
dbClose();
}
return result;
}
// 글 삭제
public int boardDel(int postno) {
int result = 0;
try {
dbConn();
sql = "DELETE FROM board_tbl WHERE postno=?";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, postno);
result = pstmt.executeUpdate();
}catch(Exception e) {
e.printStackTrace();
}finally {
dbClose();
}
return result;
}
}
DAO에 있는 메소드들은 각자 역할에 맞게 DB를 접속하여 쿼리문을 날리고, 알맞은 데이터를 처리하게 된다.
- boardListAll() - board_tbl에서 게시글에 대한 데이터를 불러온다.
- boardSelectOne() - 선택한 게시글의 내용을 보거나 수정한다.
- hitCount() - 게시글을 선택했을때, 조회수를 하나 증가시킨다.
- boardPost() - 글을 등록시킨다.
- boardEdit() - 글을 수정시킨다.
- boardDel() - 글을 삭제시킨다.
이렇게 만든 DAO들은 각자 역할에 맞게 jsp의 앞 부분에서 실행되어진다.
boardList.jsp
<%@page import="com.multi.app.board.BoardDTO"%>
<%@page import="java.util.List"%>
<%@page import="com.multi.app.board.BoardDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
// 게시판 목록에서 DB조회
BoardDAO dao = new BoardDAO();
List<BoardDTO> lst = dao.boardListAll();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Board List</title>
<style>
.container{
width:1000px;
margin:0 auto;
/* background:#ddd; */
}
ul, li{
margin:0;
padding:0;
list-style-type:none;
}
#lst>li{
float:left;
width:10%;
height:40px;
line-height:40px;
border-bottom:1px solid #ddd;
}
#lst>li:nth-child(5n+2){
width:55%;
}
#lst>li:nth-child(5n+5){
width:15%;
/* background:blue; */
}
.wordCut{
white-spce:nowrap; /* 줄 안바꾸기 */
overflow:hidden; /* 넘친 데이터 숨기기 */
text-overflow:ellipsis; /* ...표시하기 */
}
</style>
</head>
<body>
<div class="container">
<h1>Board List</h1>
<div>
<a href="/webApp/board/boardWrite.jsp">New</a>
</div>
<ul id="lst">
<li>No.</li>
<li>Title</li>
<li>Author</li>
<li>Hit</li>
<li>Date</li>
<%-- <%
for(int i=0; i<lst.size(); i++){ // List에 담긴 ResultSet 데이터를 반복문으로 출력
BoardDTO dto = lst.get(i);
%>
<li><%= dto.getPostno() %></li>
<li><%= dto.getSubject() %></li>
<li><%= dto.getUsername() %></li>
<li><%= dto.getHitcount() %></li>
<li><%= dto.getRegdate() %></li>
<%
}
%> --%>
<!-- jstl로 목록 출력하기 -->
<c:forEach var="dto2" items="<%= lst %>">
<li>${ dto2.postno }</li>
<li class="wordCut"><a href="/webApp/board/boardView.jsp?postno=${ dto2.postno }">${ dto2.subject }</a></li> <!-- 글 제목에 해당 글 내용 조회페이지 링크등록 -->
<li>${ dto2.username }</li>
<li>${ dto2.hitcount }</li>
<li>${ dto2.regdate }</li>
</c:forEach>
</ul>
</div>
</body>
</html>
boardView.jsp
<%@page import="com.multi.app.board.BoardDTO"%>
<%@page import="com.multi.app.board.BoardDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<% request.setCharacterEncoding("UTF-8"); %>
<%
// 게시판 목록에서 제목을 선택하여 글 내용 보기로 이동
// 제목 선택 시 보내준 postno를 request한다
int postno = Integer.parseInt(request.getParameter("postno"));
int part = Integer.parseInt(request.getParameter("part"));
// postno에 해당되는 데이터를 DB에서 선택해야한다
BoardDAO dao = new BoardDAO();
// 데이터 선택, 조회수 +1
BoardDTO dto = dao.boardSelectOne(postno, part);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>View Post</title>
<style>
.container{
width:1000px;
margin: 0 auto;
}
ul,li{
margin:0;
padding:0;
list-style-type:none;
}
li{
float:left;
width:10%;
margin:10px, 0;
}
li:nth-child(2n){
width:90%;
}
</style>
<script>
// 현재 글 삭제 확인 함수
// yes : 삭제, no : 취소
function verifyDel(){
// 대화상자 : alert, confirm, prompt
// alert() -> 통보, 확인버튼 1개
// alert("확인 대화상자");
// confirm() -> 확인, 예(true)/아니오(false)
// confirm("confirm");
// prompt() -> 값을 입력할 수 있음
// prompt("prompt", "John Smith");
if(confirm("Are you sure you want to delete the post?")){
// 삭제를 구현하는 페이지로 데이터를 가지고 이동한다
location.href = "/webApp/board/boardDel.jsp?postno=<%= dto.getPostno() %>";
}
}
</script>
</head>
<body>
<div class="container">
<h1>View post content</h1>
<% if(dto.getSubject()!=null){ %>
<ul>
<li>Post No.</li>
<li><%= dto.getPostno() %></li>
<li>Author</li>
<li><%= dto.getUsername() %>, Date: <%= dto.getRegdate() %>, Views: <%= dto.getHitcount() %></li>
<li>Title</li>
<li><%= dto.getSubject() %></li>
<li>Content</li>
<li><%= dto.getContent() %></li>
</ul>
<div>
<a href="/webApp/board/boardEdit.jsp?postno=<%= dto.getPostno() %>">Edit</a>
<a href="javascript:verifyDel()">Delete</a> <!-- a태그의 href속성값에 javascript:function()을 쓰면 자바스크립트 함수를 호출한다 -->
<a href="/webApp/board/boardList.jsp">List</a>
</div>
<% }else{
out.println("<h2>The post doesn't exist.</h2>");
} %>
</div>
</body>
</html>
boardWrite.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>New article</title>
<!-- jquery홈페이지에서 CDN 링크 불러오기 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<style>
ul,li{
padding:0;
margin:0;
list-style-type:none;
}
.container{
width:1000px;
margin:0 auto;
}
#subject{
width:700px;
}
#content{
width:100%;
height:200px;
}
</style>
<script>
$(function(){
// jquery는 body가 실행된 후에 적용된다
// form에서 submit이벤트가 발생하면 처리할 이벤트 함수
$("#writeForm").submit(function(){
if($("#username").val()==""){ // username이 있는지 확인
alert("Author is empty");
return false;
}
if($("#subject").val()==""){
alert("Title is empty");
return false;
}
if($("#content").val()==""){
alert("Content is empty");
return false;
}
return true;
});
});
</script>
</head>
<body>
<div class="container">
<h1>New post</h1>
<form method="post" action="/webApp/board/boardWriteOk.jsp" id="writeForm">
<ul>
<li>Author : <input type="text" name="username" id="username" value="poby"></li>
<li>Title : <input type="text" name="subject" id="subject"></li>
<li>Content<br>
<textarea name="content" id="content"></textarea></li>
<li><input type="submit" value="Post"></li>
</ul>
</form>
</div>
<div>
<a href="/webApp/">Home</a>
<a href="/webApp/board/boardList.jsp">List</a>
</div>
</body>
</html>
boardWriteOk.jsp
<%@page import="com.multi.app.board.BoardDAO"%>
<%@page import="com.multi.app.board.BoardDTO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<% request.setCharacterEncoding("UTF-8"); %>
<%
// boardWrite.jsp에서 form으로 보내준 데이터를 request로 받아서 DTO에 등록한다
/* BoardDTO dto = new BoardDTO();
dto.setUsername(request.getParameter("username"));
dto.setSubject(request.getParameter("subject"));
dto.setContent(request.getParameter("content")); */
%>
<!--
Bean, Beans 객체 생성
action태그 useBean은 객체를 생성한다
id : 객체 이름
class : 클래스 이름
scope : 유효 범위
-->
<jsp:useBean id="dto" class="com.multi.app.board.BoardDTO" scope="page"></jsp:useBean> <!-- BoardDTO dto = new BoardDTO(); -->
<!-- action태그 setProperty는 이전 페이지 값을 request해서 DTO객체에 세팅해준다. -->
<jsp:setProperty name="dto" property="*"></jsp:setProperty> <!-- dto.set~~(); -->
<%
dto.setIpAddr(request.getRemoteAddr()); // username의 ip주소
BoardDAO dao = new BoardDAO();
int result = dao.boardPost(dto); // 글 등록
if(result>0){ // 글 등록 성공 -> Board List로 이동
response.sendRedirect("/webApp/board/boardList.jsp");
}else{ // 글 등록 실패 -> Board Write로 이동
%>
<script>
alert("Failed to post.");
history.back(); // history.go(-1);
</script>
<%
}
%>
게시판에 글을 작성하는것까지 만들었다.
다음엔 수정 및 삭제하는 코드를 작성하자.