웹개발 교육/jsp

[51~52일] jsp (18) - myweb 프로젝트(게시판)

ewok 2022. 10. 11. 18:17

게시판

bbs 폴더를 생성하여 template.jsp를 복사해서 붙여 넣고 파일명을 bbsList.jsp로 변경한다.

 

 

bbsList.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="../header.jsp"%>
<!-- 본문 시작 template.jsp-->
<h3>* 글 목록 *</h3>
<p><a href="bbsForm.jsp">[글쓰기]</a></p>
<!-- 본문 끝 -->
<%@ include file="../footer.jsp"%>

 

bbsList.jsp 페이지소스

header.jsp와 footer.jsp로 만들었던 부분이 잘 들어가 있다.

 

다음으로 게시판 form을 만들어 보자

bbs 폴더에 template.jsp를 복사해서 bbsForm.jsp를 만든다.

 

bbsForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="../header.jsp"%>
<!-- 본문 시작 bbsForm.jsp-->
<h3>* 글쓰기 *</h3>
<p><a href="bbsList.jsp">[글목록]</a></p>

<div class="container">
	<form name="bbsfrm" id="bbsfrm">
	<table class="table">
	<tr>
	   <th class="success">작성자</th>
	   <td><input type="text" name="wname" id="wname" class="form-control" maxlength="20" required></td>
	</tr>
	<tr>
	   <th class="success">제목</th>
	   <td><input type="text" name="subject" id="subject" class="form-control" maxlength="100" required></td>
	</tr>
	<tr>
	   <th class="success">내용</th>
	   <td><textarea rows="5"  class="form-control" name="content" id="content"></textarea></td>
	</tr>
	<tr>
	   <th class="success">비밀번호</th>
	   <td><input type="password" name="passwd" id="passwd" class="form-control" maxlength="10" required></td>
	</tr>
	<tr>
	    <td colspan="2" align="center">
	       <input type="submit" value="쓰기" class="btn btn-success">
	       <input type="reset"  value="취소" class="btn btn-danger">
	    </td>
	</table>	
	</form>
</div>

<!-- 본문 끝 -->
<%@ include file="../footer.jsp"%>

 

 

이제 테이블을 설계할 차례이다. 예전에 언급했듯이 JDBC 방식과 JPA 방식이 있다. JDBC 방식으로 진행할 것이다.

 

※ 참고

 

sql 폴더를 만들어 bbs.sql 파일을 생성한다.

 

bbs.sql

--bbs.sql
--답변 및 댓글형 게시판

--테이블 삭제
drop table tb_bbs;

--테이블 생성
create table tb_bbs(
  bbsno    number(5)       not null -- 일련번호 -99999~99999
 ,wname    varchar2(20)    not null -- 작성자
 ,subject  varchar2(100)   not null -- 글제목
 ,content  varchar2(2000)  not null -- 글내용
 ,passwd   varchar2(10)    not null -- 글비밀번호
 ,readcnt  number(5)       default 0 not null -- 글조회수
,regdt    date            default  sysdate   -- 글작성일
 ,grpno    number(5)       not null  -- 글 그룹번호
 ,indent   number(5)       default 0 -- 들여쓰기
 ,ansnum   number(5)       default 0 -- 글순서
 ,ip       varchar2(15)    not null  -- 사용자 요청 PC의 IP
 ,primary key(bbsno)                 --bbsno 기본키 
);

--시퀀스 생성
create sequence bbs_seq;

--시퀀스 삭제
drop sequence bbs_seq;

--명령어 완료
commit;
////////////////////////////////////////

--새글쓰기
bbsno                           : 시퀀스를 이용해서 일련번호
wname, subject, content, passwd : 사용자가 입력
readcnt, regdt, indent, ansum   : default 값
ip                              : 요청 pc의 IP 저장
grpno                           : max(bbsno)+1


--그룹번호(grpno) 만들기
select max(bbsno) from tb_bbs;
--null값이면 계산 안됨
select max(bbsno)+1 from tb_bbs;
--nvl() 함수를 이용해서 max(bbsno)갑싱 비어있을 때(null) 0으로 바꿈
select nvl(max(bbsno),0) from tb_bbs;
--nvl() 함수를 이용해서 max(bbsno)갑싱 비어있을 때(null) 0으로 바꾼 후 +1
select nvl(max(bbsno),0)+1 from tb_bbs;

--행추가
INSERT INTO tb_bbs(bbsno, wname, subject, content, passwd, ip, grpno)
VALUES (bbs_seq.nextval, ?, ?, ?, ?, ?, (select nvl(max(bbsno),0)+1 from tb_bbs));

 

테이블과 시퀀스를 생성하자

 

 

다음으로 Backend를 작업할 차례이다.

net.bbs 패키지에 BbsDAO와 BbsDTO 클래스를 생성한다.

 

 

BbsDTO.java

package net.bbs;

public class BbsDTO { //전송 객체
	//멤버변수 field
	private int bbsno;
	private String wname;
	private String subject;
	private String content;
	private String passwd;
	private int readcnt;
	private String regdt;
	private int grpno;
	private int indent;
	private int ansnum;
	private String ip;
	
	//생성자 함수 constructor
	public BbsDTO() {}

	//getter, setter
	public int getBbsno() {
		return bbsno;
	}

	public void setBbsno(int bbsno) {
		this.bbsno = bbsno;
	}

	public String getWname() {
		return wname;
	}

	public void setWname(String wname) {
		this.wname = wname;
	}

	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 getPasswd() {
		return passwd;
	}

	public void setPasswd(String passwd) {
		this.passwd = passwd;
	}

	public int getReadcnt() {
		return readcnt;
	}

	public void setReadcnt(int readcnt) {
		this.readcnt = readcnt;
	}

	public String getRegdt() {
		return regdt;
	}

	public void setRegdt(String regdt) {
		this.regdt = regdt;
	}

	public int getGrpno() {
		return grpno;
	}

	public void setGrpno(int grpno) {
		this.grpno = grpno;
	}

	public int getIndent() {
		return indent;
	}

	public void setIndent(int indent) {
		this.indent = indent;
	}

	public int getAnsnum() {
		return ansnum;
	}

	public void setAnsnum(int ansnum) {
		this.ansnum = ansnum;
	}

	public String getIp() {
		return ip;
	}

	public void setIp(String ip) {
		this.ip = ip;
	}

	@Override
	public String toString() {
		return "BbsDTO [bbsno=" + bbsno + ", wname=" + wname + ", subject=" + subject + ", content=" + content
				+ ", passwd=" + passwd + ", readcnt=" + readcnt + ", regdt=" + regdt + ", grpno=" + grpno + ", indent="
				+ indent + ", ansnum=" + ansnum + ", ip=" + ip + "]";
	}
		
	
}//class end

 

 

BbsDAO.java

package net.bbs;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import net.utility.DBClose;
import net.utility.DBOpen;

public class BbsDAO { //데이터베이스 관련 작업
	
	private DBOpen dbopen = null;
	private Connection con = null;
	private PreparedStatement pstmt = null;
	private ResultSet rs = null;
	private StringBuilder sql = null;
	
	public BbsDAO() {
		dbopen = new DBOpen();
	}//end
	
	public int create(BbsDTO dto) {
		int cnt = 0;
		try {
			con = dbopen.getConection(); //DB연결
			
			sql = new StringBuilder();
			sql.append(" INSERT INTO tb_bbs(bbsno, wname, subject, content, passwd, ip, grpno) ");
			sql.append(" VALUES (bbs_seq.nextval, ?, ?, ?, ?, ?, (select nvl(max(bbsno),0)+1 from tb_bbs)) ");
			
			pstmt = con.prepareStatement(sql.toString());
			pstmt.setString(1, dto.getWname());
			pstmt.setString(2, dto.getSubject());
			pstmt.setString(3, dto.getContent());
			pstmt.setString(4, dto.getPasswd());
			pstmt.setString(5, dto.getIp());
			
			cnt = pstmt.executeUpdate();
			
		} catch (Exception e) {
			System.out.println("추가실패 : " + e);
		} finally {
			DBClose.close(con, pstmt);
		}//end
		return cnt;
	}//create() end
	
}//class end

 

다시 Frontend로 돌아와서

bbsForm.jsp에서 전송을 누르면 bbsIns.jsp로 이동하도록 바꾼다.

 

bbsForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="../header.jsp"%>
<!-- 본문 시작 bbsForm.jsp-->
<h3>* 글쓰기 *</h3>
<p><a href="bbsList.jsp">[글목록]</a></p>

<div class="container">
	<form name="bbsfrm" id="bbsfrm" method="post" action="bbsIns.jsp">
	<table class="table">
	<tr>
	   <th class="success">작성자</th>
	   <td><input type="text" name="wname" id="wname" class="form-control" maxlength="20" required></td>
	</tr>
	<tr>
	   <th class="success">제목</th>
	   <td><input type="text" name="subject" id="subject" class="form-control" maxlength="100" required></td>
	</tr>
	<tr>
	   <th class="success">내용</th>
	   <td><textarea rows="5"  class="form-control" name="content" id="content"></textarea></td>
	</tr>
	<tr>
	   <th class="success">비밀번호</th>
	   <td><input type="password" name="passwd" id="passwd" class="form-control" maxlength="10" required></td>
	</tr>
	<tr>
	    <td colspan="2" align="center">
	       <input type="submit" value="쓰기" class="btn btn-success">
	       <input type="reset"  value="취소" class="btn btn-danger">
	    </td>
	</table>	
	</form>
</div>

<!-- 본문 끝 -->
<%@ include file="../footer.jsp"%>

 

bbsIns.jsp를 만들기 앞서 sungjukbean에서 했던 것처럼 공통 페이지를 만들고 import 할 수 있도록 하자

 

ssi.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%-- ssi.jsp 공통코드 --%>

<%@ page import="java.sql.*"%>
<%@ page import="java.io.*"%>
<%@ page import="java.util.*"%>

<%@ page import="net.utility.*"%>
<%@ page import="net.bbs.*"%>

<jsp:useBean id="dao" class="net.bbs.BbsDAO" scope="page"></jsp:useBean>
<jsp:useBean id="dto" class="net.bbs.BbsDTO" scope="page"></jsp:useBean>

<%request.setCharacterEncoding("UTF-8");%>

 

글쓰기

다음으로 bbsIns.jsp를 만들자

 

bbsIns.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="ssi.jsp" %>
<%@ include file="../header.jsp"%>
<!-- 본문 시작 bbsIns.jsp-->
<%
	//사용자가 입력 요청한 정보를 가져오기
	String wname = request.getParameter("wname").trim();
	String subject = request.getParameter("subject").trim();
	String content = request.getParameter("content").trim();
	String passwd = request.getParameter("passwd").trim();
	String ip = request.getRemoteAddr(); //요청PC의 IP
	
	//dto 객체에 담기
	dto.setWname(wname);
	dto.setSubject(subject);
	dto.setContent(content);
	dto.setPasswd(passwd);
	dto.setIp(ip);

%>
<!-- 본문 끝 -->
<%@ include file="../footer.jsp"%>

 

 

우리는 테이블을 설계할 때 일련번호, 작성자, 글 제목 등 null값을 허용하지 않도록 제약조건을 주었다.

따라서 빈 값이나 쓰레기 값이 서버로 전송되지 않도록 제약을 걸어야 한다.

 

이 작업을 위해 잠시 bbsForm.jsp로 오면

자바스크립트를 통해 전송 시 이벤트를 걸어 게시판의 유효성 검사를 하도록 할 것이다.

 

처음에 만든 js폴더에 myscript.js 파일을 생성한다. 이 파일은 vsc를 이용하여 코딩할 것이다.

 

myscript.js

/**
 * myscript.js
 */
 
 function bbsCheck(){ //게시판 유효성 검사
 	//1)작성자 (2글자 이상 입력)
 	let wname = document.getElementById("wname").value; //작성자 가져오기
	wname = wname.trim();
	if(wname.length<2) {
		alert("작성자 2글자 이상 입력해 주세요");
		document.getElementById("wname").focus(); //작성자 칸에 커서
		return false; //전송하지 않음
	}//if end

 	//2)제목 (2글자 이상 입력)
	 let subject = document.getElementById("subject").value;
	 subject = subject.trim();
	 if(subject.length<2) {
		 alert("제목 2글자 이상 입력해 주세요");
		 document.getElementById("subject").focus();
		 return false;
	 }//if end

 	//3)내용 (2글자 이상 입력)
	 let content = document.getElementById("content").value;
	 content = content.trim();
	 if(content.length<2) {
		 alert("내용 2글자 이상 입력해 주세요");
		 document.getElementById("content").focus();
		 return false;
	 }//if end

 	//4)비밀번호 (4자리 이상 & 숫자형 기호만 입력)
	 let passwd = document.getElementById("passwd").value;
	 passwd = passwd.trim();
	 if(passwd.length<4 || isNaN(passwd)) {
		 alert("비밀번호 4글자 이상 숫자로 입력해 주세요");
		 document.getElementById("passwd").focus(); //작성자 칸에 커서
		 return false; //전송하지 않음
	 }//if end
	
	return true; //onsubmit 이벤트에서 서버로 전송

}//bbscheck() end

 

Backend단에서는 연두색 박스인 name으로, frontend 단에서는 빨간색 박스인 id를 이용하는 것을 추천한다.

 

 

 

글목록

글목록을 클릭하면 등록된 글의 목록들이 나오도록 페이지를 만들자

 

bbsList.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="ssi.jsp"%>
<%@ include file="../header.jsp"%>
<!-- 본문 시작 bbsLIst.jsp-->
<h3>* 글 목록 *</h3>
<p><a href="bbsForm.jsp">[글쓰기]</a></p>
<div>
	<table>
	<thead>
		<tr>
			<th>제목</th>
			<th>조회수</th>
			<th>작성자</th>
			<th>작성일</th>
		</tr>
	</thead>
	<tbody>
<%
	ArrayList<BbsDTO> list = dao.list();
	if(list==null){
		out.println("<tr>");
		out.println("	<td colspan='4'>");
		out.println("		<strong>관련자료 없음!!</strong>");
		out.println("	</td>");
		out.println("</tr>");
	} else {
		for(int i=0; i<list.size(); i++) {
			dto = list.get(i);
%>
			<tr>
				<td><%=dto.getSubject()%></td>
				<td><%=dto.getReadcnt()%></td>
				<td><%=dto.getWname()%></td>
				<td><%=dto.getRegdt().substring(0, 10)%></td>
			</tr>
<%
		}//for end
	}//if end
%>	
	</tbody>
	</table>
</div>
<!-- 본문 끝 -->
<%@ include file="../footer.jsp"%>

 

다음으로 list()를 만들 차례이다. BbsDAO.java로 가서 만든다.

 

BbsDAO.java

public ArrayList<BbsDTO> list() {
    ArrayList<BbsDTO> list = null;
    try {
        con = dbopen.getConection();

        sql = new StringBuilder();
        sql.append(" SELECT bbsno, wname, subject, readcnt, regdt, indent ");
        sql.append(" FROM tb_bbs ");
        sql.append(" ORDER BY grpno DESC, ansnum ASC ");

        pstmt = con.prepareCall(sql.toString());
        rs = pstmt.executeQuery();
        if(rs.next()) {
            list = new ArrayList<>();
            do {
                BbsDTO dto = new BbsDTO(); //한줄담기
                dto.setBbsno(rs.getInt("bbsno"));
                dto.setWname(rs.getString("wname"));
                dto.setSubject(rs.getString("subject"));
                dto.setReadcnt(rs.getInt("readcnt"));
                dto.setRegdt(rs.getString("regdt"));
                dto.setIndent(rs.getInt("indent"));
                list.add(dto); //list 저장
            } while(rs.next());
        }//if end			

    } catch (Exception e) {
        System.out.println("전체목록실패:" + e);
    } finally {
        DBClose.close(con, pstmt, rs);
    }//end
    return list;
}//list() end

 

보통 당일에 올라온 글은 new와 같은 표시가 되어있다. 우리도 new가 표시되게 한번 해 보자

 

그전에 아래 파일을 받아 net.utility 패키지에 넣어 사용할 수 있도록 하자 (유용한 메서드들이 담겨 있으니 추후에도 활용할 수 있다.)

Utility.java
0.03MB

new 이미지 파일

new.gif
0.00MB

 

BbsDAO.java

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="ssi.jsp"%>
<%@ include file="../header.jsp"%>
<!-- 본문 시작 bbsLIst.jsp-->
<h3>* 글 목록 *</h3>
<p><a href="bbsForm.jsp">[글쓰기]</a></p>
<div>
	<table>
	<thead>
		<tr>
			<th>제목</th>
			<th>조회수</th>
			<th>작성자</th>
			<th>작성일</th>
		</tr>
	</thead>
	<tbody>
<%
	ArrayList<BbsDTO> list = dao.list();
	if(list==null){
		out.println("<tr>");
		out.println("	<td colspan='4'>");
		out.println("		<strong>관련자료 없음!!</strong>");
		out.println("	</td>");
		out.println("</tr>");
	} else {
		
		//오늘 날짜를 문자열 "2022-10-22" 만들기
		String today = Utility.getDate();
		
		for(int i=0; i<list.size(); i++) {
			dto = list.get(i);
%>
			<tr>
				<td style="text-align: left">
					<%=dto.getSubject()%>
<%
					//오늘 작성한 글제목 뒤에 new 이미지 출력
					//작성일(regdt)에서 "년월일"만 자르기
					String regdt = dto.getRegdt().substring(0, 10);
					if(regdt.equals(today)){ //작성일과 오늘 날짜가 같다면
						out.println("<img src='../images/new.gif'>");
					}//if end
%>					
				</td>
				<td><%=dto.getReadcnt()%></td>
				<td><%=dto.getWname()%></td>
				<td><%=dto.getRegdt().substring(0, 10)%></td>
			</tr>
<%
		}//for end
	}//if end
%>	
	</tbody>
	</table>
</div>
<!-- 본문 끝 -->
<%@ include file="../footer.jsp"%>

 

그리고 조회수가 일정 수를 넘어가면 인기글 같은 게 붙는 것을 본 적이 있을 것이다.

우리는 new 뒤에 hot 이미지가 나오게 해 보자

hot.gif
0.00MB

        <tr>
            <td style="text-align: left">
                <%=dto.getSubject()%>
<%
                //오늘 작성한 글제목 뒤에 new 이미지 출력
                //작성일(regdt)에서 "년월일"만 자르기
                String regdt = dto.getRegdt().substring(0, 10);
                if(regdt.equals(today)){ //작성일과 오늘 날짜가 같다면
                    out.println("<img src='../images/new.gif'>");
                }//if end

                //조회수가 10 이상이면 hot이미지 출력
                if(dto.getReadcnt()>=10) {
                    out.println("<img src='../images/hot.gif'>");
                }//if end
%>					
            </td>

 

이번에는 하단에 전체 글 개수가 표시되게 해 보자

 

bbsList.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="ssi.jsp"%>
<%@ include file="../header.jsp"%>
<!-- 본문 시작 bbsLIst.jsp-->
<h3>* 글 목록 *</h3>
<p><a href="bbsForm.jsp">[글쓰기]</a></p>
<div>
	<table>
	<thead>
		<tr>
			<th>제목</th>
			<th>조회수</th>
			<th>작성자</th>
			<th>작성일</th>
		</tr>
	</thead>
	<tbody>
<%
	ArrayList<BbsDTO> list = dao.list();
	if(list==null){
		out.println("<tr>");
		out.println("	<td colspan='4'>");
		out.println("		<strong>관련자료 없음!!</strong>");
		out.println("	</td>");
		out.println("</tr>");
	} else {
		
		//오늘 날짜를 문자열 "2022-10-22" 만들기
		String today = Utility.getDate();
		
		for(int i=0; i<list.size(); i++) {
			dto = list.get(i);
%>
			<tr>
				<td style="text-align: left">
					<%=dto.getSubject()%>
<%
					//오늘 작성한 글제목 뒤에 new 이미지 출력
					//작성일(regdt)에서 "년월일"만 자르기
					String regdt = dto.getRegdt().substring(0, 10);
					if(regdt.equals(today)){ //작성일과 오늘 날짜가 같다면
						out.println("<img src='../images/new.gif'>");
					}//if end
					
					//조회수가 10 이상이면 hot이미지 출력
					if(dto.getReadcnt()>=10) {
						out.println("<img src='../images/hot.gif'>");
					}//if end
%>					
				</td>
				<td><%=dto.getReadcnt()%></td>
				<td><%=dto.getWname()%></td>
				<td><%=dto.getRegdt().substring(0, 10)%></td>
			</tr>
<%
		}//for end
		
		//글갯수
		int totalRecord = dao.count();
		out.println("<tr>");
		out.println("	<td colspan='4' style='text-align:center;'>");
		out.println("		글갯수:<strong> " + totalRecord + " </strong>");
		out.println("	</td>");
		out.println("</tr>");
		
	}//if end
%>	
	</tbody>
	</table>
</div>
<!-- 본문 끝 -->
<%@ include file="../footer.jsp"%>

 

BbsDAO.java

public int count() {
    int cnt = 0;
    try {
        con = dbopen.getConection();

        sql = new StringBuilder();
        sql.append(" SELECT COUNT(*) as cnt ");
        sql.append(" FROM tb_bbs ");

        pstmt = con.prepareStatement(sql.toString());
        rs = pstmt.executeQuery();
        if(rs.next()) {
            cnt = rs.getInt("cnt");
        }//if end

    } catch (Exception e) {
        System.out.println("글갯수실패:" + e);
    } finally {
        DBClose.close(con, pstmt, rs);
    }//end
    return cnt;
}//count() end

 

 

 

스마트폰으로 아래 주소에 접속해서 글을 쓰면 정상적으로 추가가 된다.

http://pc ip주소:9090/myweb/bbs/bbsList.jsp

참고로 ip주소는 명령 프롬프트에서 ipconfig를 입력하면 볼 수 있다. ip주소 뒤 :9090은 처음에 톰캣을 설치했을 때 변경했던 포트번호이다.

https://ewok.tistory.com/180

 

[47일] jsp (1) - 개요 및 Tomcat 설치

jsp를 들어가기에 앞서 서버에 대해 알아보자 우리가 수업을 하면서 관리하고 있는 서버가 하나 있다. 바로 Database Server - Oracle XE 18c이다. 이외에도 Mail Server(pop3, smtp), Web Server(Tomcat, JBoss..

ewok.tistory.com

 

 

상세보기

 

bbsRead.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="ssi.jsp"%>
<%@ include file="../header.jsp"%>
<!-- 본문 시작 bbsRead.jsp-->
<h3>*게시판 상세보기 *</h3>
<p>
	<a href="bbsForm.jsp">[글쓰기]</a>
	&nbsp;&nbsp;
	<a href="bbsList.jsp">[글목록]</a>
</p>
<div class="container">
<%
	int bbsno = Integer.parseInt(request.getParameter("bbsno"));
	dto = dao.read(bbsno);
	if(dto==null){
		out.print("해당 글 없음!!");
	} else {
		dao.incrementCnt(bbsno); //조회수 증가
%>
		<table class="table">
		<tr>
			<th class="success">제목</th>
			<td><%=dto.getSubject()%></td>
		</tr>
		<tr>
			<th class="success">내용</th>
			<td style="text-align: left">
<%
				//특수문자로 치환하기
				//사용자가 입력한 엔터를 <br>태그로 바꾸기
				String content = Utility.convertChar(dto.getContent());
				out.print(content);
%>			
			</td>
		</tr>		
		<tr>
			<th class="success">조회수</th>
			<td><%=dto.getReadcnt()%></td>
		</tr>
		<tr>
			<th class="success">작성자</th>
			<td><%=dto.getWname()%></td>
		</tr>
		<tr>
			<th class="success">작성일</th>
			<td><%=dto.getRegdt()%></td>
		</tr>
		<tr>
			<th class="success">IP</th>
			<td><%=dto.getIp()%></td>
		</tr>								
		</table>
		<br>
		<input type="button" value="답변쓰기" onclick="location.href='bbsReply.jsp'">
		<input type="button" value="수정" onclick="location.href='bbsUpdate.jsp?bbsno=<%=bbsno%>'">
		<input type="button" value="삭제" onclick="location.href='bbsDel.jsp?bbsno=<%=bbsno%>'">
<%		
	}//if end
%>
</div>

<!-- 본문 끝 -->
<%@ include file="../footer.jsp"%>

 

bbsList.jsp에서 bbsno를 넘겨주었으니 그것을 request.getParameter()로 가져왔다.

 

이제 read()와 incrementCnt()를 만들어보겠다.

 

BbsDAO.java

public BbsDTO read(int bbsno) {
    BbsDTO dto = null;
    try {
        con = dbopen.getConection();

        sql = new StringBuilder();
        sql.append(" SELECT bbsno, wname, subject, content, readcnt, regdt, ip, grpno, indent, ansnum ");
        sql.append(" FROM tb_bbs ");
        sql.append(" WHERE bbsno=? ");

        pstmt = con.prepareStatement(sql.toString());
        pstmt.setInt(1, bbsno);

        rs = pstmt.executeQuery();
        if(rs.next()) {
            dto = new BbsDTO();
            dto.setBbsno(rs.getInt("bbsno"));
            dto.setWname(rs.getString("wname"));
            dto.setSubject(rs.getString("subject"));
            dto.setContent(rs.getString("content"));
            dto.setReadcnt(rs.getInt("readcnt"));
            dto.setRegdt(rs.getString("regdt"));
            dto.setIp(rs.getString("ip"));
            dto.setGrpno(rs.getInt("grpno"));
            dto.setIndent(rs.getInt("indent"));
            dto.setAnsnum(rs.getInt("ansnum"));
        }//end

    } catch (Exception e) {
        System.out.println("상세보기 실패:" + e);
    } finally {
        DBClose.close(con, pstmt, rs);
    }
    return dto;
}//read() end

public void incrementCnt(int bbsno) {
    try {
        con = dbopen.getConection();

        sql = new StringBuilder();
        sql.append(" update tb_bbs ");
        sql.append(" set readcnt=readcnt+1 ");
        sql.append(" where bbsno=? ");

        pstmt = con.prepareStatement(sql.toString());
        pstmt.setInt(1, bbsno);
        pstmt.executeQuery();			

    } catch (Exception e) {
        System.out.println("조회수 증가 실패 : " + e);
    } finally {
        DBClose.close(con, pstmt);
    }//end
}//incrementCnt() end

 

새로고침을 하면 조회수가 증가하는 것을 볼 수 있다. 또한 조회수가 10 이상이면 hot 그림이 표시된다.

 

 

 

삭제

글을 썼을 때 비밀번호를 입력하게 했다. 삭제 시에는 글쓰기에서 입력한 비밀번호와 일치해야 글을 삭제할 수 있도록 만드려고 한다. 그러기 위해서는 비밀번호를 입력할 수 있도록 페이지를 만들어야 한다.

 

bbsDel.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="../header.jsp"%>
<!-- 본문 시작 bbsDel.jsp-->
<!-- 글번호(bbsno)와 비밀번호(passwd)가 일치하면 글삭제 -->
<h3>* 글삭제 *</h3>
<p><a href="bbsList.jsp">[글목록]</a></p>
<%
	int bbsno = Integer.parseInt(request.getParameter("bbsno"));
%>
<div class="container">
	<form method="post" action="bbsDelProc.jsp" onsubmit="return pwCheck()"> <!-- myscript.js -->
	<input type="hidden" name="bbsno" value="<%=bbsno%>">
		<table class="table">
		<tr>
			<th class="success">비밀번호</th>
			<td><input type="password" name="passwd" id="passwd" required></td>
		</tr>
		<tr>
			<td colspan="2">
				<input type="submit" value="삭제" class="btn btn-danger">
			</td>
		</tr>
		</table>
	</form>
</div>
<!-- 본문 끝 -->
<%@ include file="../footer.jsp"%>

 

사용자가 입력한 비밀번호가 DB에 입력되어 있는 비밀번호와 일치하는지 확인하는 작업이 필요하다. 그러기 위해 onsubmit 속성에 비밀번호를 체크하는 함수를 만들어 이를 확인하도록 하자

 

myscript.js

function pwCheck() {
	let passwd = document.getElementById("passwd").value;
	passwd = passwd.trim();
	if(passwd.length<4 || isNaN(passwd)) {
		alert("비밀번호 4글자 이상 숫자로 입력해 주세요");
		document.getElementById("passwd").focus(); //작성자 칸에 커서
		return false;
	}//if end

	let message = "진행된 내용은 복구되지 않습니다.\n계속 진행할까요?";
	if(confirm(message)) { //확인 true, 취소 false
		return true; //서버로 전송
	} else {
		return false;
	}//if end

}//pwCheck() end

 

 

bbsDelProc.jsp

삭제 처리하는 페이지

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="ssi.jsp" %>
<%@ include file="../header.jsp"%>
<!-- 본문 시작 bbsDelProc.jsp-->
<h3>* 글 삭제 *</h3>

<%
	int bbsno = Integer.parseInt(request.getParameter("bbsno"));
	String passwd = request.getParameter("passwd").trim();
	
	dto.setBbsno(bbsno);
	dto.setPasswd(passwd);
	
	int cnt = dao.delete(dto);
	if(cnt==0){
		out.println("<p>비밀번호가 일치하지 않습니다</p>");
		out.println("<p><a href='javascript:history.back()'>[다시시도]</a></p>");
	} else {
		out.println("<script>");
		out.println("	alert('게시글이 삭제되었습니다.');");
		out.println("	location:href='bbsList.jsp';"); //목록페이지 이동
		out.println("</script>");
	}//if end
%>	
<!-- 본문 끝 -->
<%@ include file="../footer.jsp"%>

 

BbsDAO.java

public int delete(BbsDTO dto) {
    int cnt = 0;
    try {

        con = dbopen.getConection();
        sql = new StringBuilder();
        sql.append(" delete from tb_bbs ");
        sql.append(" where bbsno=? and passwd=? ");

        pstmt = con.prepareStatement(sql.toString());
        pstmt.setInt(1, dto.getBbsno());
        pstmt.setString(2, dto.getPasswd());
        cnt = pstmt.executeUpdate();

    } catch (Exception e) {
        System.out.println("삭제 실패:" + e);
    } finally {
        DBClose.close(con, pstmt);
    }//end
    return cnt;
}//delete() end

 

bbsDel.jsp에서 폼을 통해 전송받은 글 번호와 비밀번호를 bbsDelProc.jsp로 가져와 dto 객체에 입력하였다. 그리고 delete() 함수에서 dto를 매개변수로 받아 where 조건문을 통해 해당 글 번호와 사용자가 입력한 비밀번호 모두 만족하는 행을 찾아 삭제하도록 쿼리문을 작성하였다. 만약 비밀번호가 틀렸다면 글을 찾을 수 없어 삭제할 수 없게 된다.

 

 

 

 

수정

bbsUpdate.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="ssi.jsp"%>
<%@ include file="../header.jsp"%>
<!-- 본문 시작 template.jsp-->
<!-- 글번호가 일치하는 행을 가져와서, 수정폼에 출력하기 -->
<h3>* 게시판 수정 *</h3>
<p>
	<a href="bbsForm.jsp">[글쓰기]</a>
	&nbsp;&nbsp;
	<a href="bbsList.jsp">[글목록]</a>
</p>

<div class="container">
<%
	int bbsno = Integer.parseInt(request.getParameter("bbsno")); //수정 글번호
	dto = dao.read(bbsno); //글번호가 일치하는 행을 가져오기
	if(dto==null){
		out.println("해당 글 없음!!");
	} else {
%>
		<form name="bbsfrm" id="bbsfrm" method="post" action="bbsUpdateProc.jsp" onsubmit="return bbsCheck()"> <!-- myscript.js -->
			<input type="hidden" name="bbsno" value="<%=bbsno%>">
			<table class="table">
			<tr>
			   <th class="success">작성자</th>
			   <td><input type="text" name="wname" id="wname" value="<%=dto.getWname()%>" class="form-control" maxlength="20" required></td>
			</tr>
			<tr>
			   <th class="success">제목</th>
			   <td><input type="text" name="subject" id="subject" value="<%=dto.getSubject()%>" class="form-control" maxlength="100" required></td>
			</tr>
			<tr>
			   <th class="success">내용</th>
			   <td><textarea rows="5"  class="form-control" name="content" id="content"><%=dto.getContent()%></textarea></td>
			</tr>
			<tr>
			   <th class="success">비밀번호</th>
			   <td><input type="password" name="passwd" id="passwd" class="form-control" maxlength="10" required></td>
			</tr>
			<tr>
			    <td colspan="2" align="center">
			       <input type="submit" value="수정" class="btn btn-success">
			       <input type="reset"  value="취소" class="btn btn-danger">
			    </td>
			</table>
		</form>
<%		
	}//if end

%>
</div>
<!-- 본문 끝 -->
<%@ include file="../footer.jsp"%>

 

bbsUpdateProc.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="ssi.jsp" %>
<%@ include file="../header.jsp"%>
<!-- 본문 시작 bbsDelProc.jsp-->
<!-- 수정 요청한 정보를 가져와서, DB에 가서 행 수정하기 -->
<h3>* 글 수정 *</h3>

<%
	//수정 요청한 정보 가져오기
	int bbsno = Integer.parseInt(request.getParameter("bbsno"));
	String wname = request.getParameter("wname").trim();
	String subject = request.getParameter("subject").trim();
	String content = request.getParameter("content").trim();
	String passwd = request.getParameter("passwd").trim();
	String ip = request.getRemoteAddr();
	
	//dto에 담기
	dto.setBbsno(bbsno);
	dto.setWname(wname);
	dto.setSubject(subject);
	dto.setContent(content);
	dto.setPasswd(passwd);
	dto.setIp(ip);
	
	int cnt = dao.updateproc(dto);
	if(cnt==0){
		out.println("<p>비밀번호가 일치하지 않습니다</p>");
		out.println("<p><a href='javascript:history.back()'>[다시시도]</a></p>");
	} else {
		out.println("<script>");
		out.println("	alert('게시글이 수정되었습니다.');");
		out.println("	location.href='bbsList.jsp';"); //목록페이지 이동
		out.println("</script>");
	}//if end
%>	
<!-- 본문 끝 -->
<%@ include file="../footer.jsp"%>

 

bbsDAO.java

public int updateproc(BbsDTO dto) {
    int cnt = 0;
    try {
        con = dbopen.getConection();
        sql = new StringBuilder();
        sql.append(" UPDATE tb_bbs ");
        sql.append(" SET wname=? ");
        sql.append(" , subject=? ");
        sql.append(" , content=? ");
        sql.append(" , ip=? ");
        sql.append(" WHERE bbsno=? AND passwd=? ");

        pstmt = con.prepareStatement(sql.toString());
        pstmt.setString(1, dto.getWname());
        pstmt.setString(2, dto.getSubject());
        pstmt.setString(3, dto.getContent());
        pstmt.setString(4, dto.getIp());
        pstmt.setInt(5, dto.getBbsno());
        pstmt.setString(6, dto.getPasswd());

        cnt = pstmt.executeUpdate();

    } catch (Exception e) {
        System.out.println("수정 실패:" + e);
    } finally {
        DBClose.close(con, pstmt);
    }
    return cnt;
}//update() end