반응형
게시판 구현하기
작업에 사용할 파일 미리 다운받아서 준비
준비작업
DB설치, DB연동 라이브러리 추가 및 웹 환경설정을 해야 한다.
이클립스에서 인코딩 관련 문제가 발생할 수 있으므로 모든 인코딩은 UTF-8로 통일한다.
이클립스 메뉴에서 [Window] – [Preferences] – [Web]에 보면 왼쪽과 같이 파일이 보인다.
클릭하여 모두 인코딩을 맞춰준다. 그리고 DB와 연동하기 위해 라이브러리를 추가하고 context.xml 과 web.xml 파일을 수정한다.
추가로 게시판에서 사용되는 이미지 파일을 포함한다.
1.라이브러리 추가 및 이미지 파일 추가
Connection Pool 기능을 적용시키기 위해 다음과 같이 파일을 준비한다.
위와 같이 구성 후 Build Path 설정(tomcat-dbcp, ojdbc)
2. WebContent/WEB-INF/web.xml에 추가
1
2
3
4
5
6 |
<resource-ref>
<description>ConnectionPool</description>
<res-ref-name>jdbc/myOracle</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref> |
cs |
3. WebContent/META-INF/context.xml 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 |
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/myOracle"
auth="Container"
driverClassName="oracle.jdbc.driver.OracleDriver"
type="javax.sql.DataSource"
url="jdbc:oracle:thin:@localhost:1521:xe"
username="데이터베이스접속계정"
password="데이터베이스접속계정비밀번호"
initialSize="50"
maxTotal="20"
maxIdle="10"
maxWaitMillis="10000" />
<!--
initialSize
: 최초 시점에 getConnection() 를 통해 커넥션 풀에 채워 넣을 커넥션 개수 (default = 0)
maxTotal (1.x에서는 maxActive):
: 동시에 사용할 수 있는 최대 커넥션 개수 (default = 8)
maxIdle
: Connection Pool에 반납할 때 최대로 유지될 수 있는 커넥션 개수 (default = 8)
minIdle
: 최소한으로 유지할 커넥션 개수 (default = 0)
maxWaitMillis (1.x에서는 maxWait)
: pool이 고갈되었을 경우 최대 대기 시간 (ms단위, default = -1 = 무한정)
-->
</Context> |
cs |
위의 준비가 완료되면 다음을 따라서 게시판 구현을 시작한다.
1. 게시판 테이블 만들기
게시판을 구현하기에 앞서 DB에 글을 저장할 테이블을 만든다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 |
create table "BOARD" (
"NUM" number(7,0) not null,
"WRITER" varchar2(12) not null,
"EMAIL" varchar2(30) not null,
"SUBJECT" varchar2(50) not null,
"PASS" varchar2(10) not null,
"READCOUNT" number(5,0) default 0 not null,
"REF" number(5,0) default 0 not null,
"STEP" number(3,0) default 0 not null,
"DEPTH" number(3,0) default 0 not null,
"REGDATE" timestamp default sysdate not null,
"CONTENT" varchar2(4000) not null,
"IP" varchar2(20) not null,
constraint "BOARD_PK" primary key ("NUM")
); |
cs |
다음 시퀀스 생성
1
2 |
create sequence "BOARD_SEQ" start with 1 increment by 1 nomaxvalue nocache nocycle;
|
cs |
이러서 MVC패턴에서 모델에 해당하는 부분인 DTO와 DAO를 작성한다.
src/boardone/BoardDto.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90 |
package boardone;
import java.sql.Timestamp;
public class BoardDto {
private int num;
private String writer;
private String email;
private String subject;
private String pass;
private int readcount;
private int ref;
private int step;
private int depth;
private Timestamp regdate;
private String content;
private String ip;
public BoardDto(){}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
public int getReadcount() {
return readcount;
}
public void setReadcount(int readcount) {
this.readcount = readcount;
}
public int getRef() {
return ref;
}
public void setRef(int ref) {
this.ref = ref;
}
public int getStep() {
return step;
}
public void setStep(int step) {
this.step = step;
}
public int getDepth() {
return depth;
}
public void setDepth(int depth) {
this.depth = depth;
}
public Timestamp getRegdate() {
return regdate;
}
public void setRegdate(Timestamp regdate) {
this.regdate = regdate;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
}
|
cs |
앞에서 회원가입 로그인을 만든 후 Singleton 개념을 적용시키자고 했었다.
이번에는 처음부터 적용해 보자.
Singleton을 유틸리티 형태로 만들어 본다.
src/boardone/ConnUtil.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 |
package boardone;
import java.sql.*;
import javax.sql.*;
import javax.naming.*;
public class ConnUtil {
private static DataSource ds;
static {
try{
InitialContext ctx = new InitialContext();
ds = (DataSource)ctx.lookup("java:comp/env/jdbc/myOracle");
} catch(NamingException e){}
}
public static Connection getConnection() throws SQLException{
return ds.getConnection();
}
} |
cs |
위에서 만든 ConnUtil에서 실제 데이터베이스에 쿼리작업을 해 줄 DAO를 만든다.
src/boardone/BoardDao.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 |
package boardone;
public class BoardDao {
private static BoardDao instance = null;
private BoardDao(){}
public static BoardDao getInstance(){
if(instance == null){
synchronized(BoardDao.class){
instance = new BoardDao();
}
}
return instance;
}
//이제부터 여기에 게시판에서 필요한 작업 기능들을 메서드로 추가하게 된다.
} |
cs |
디자인 요소 작성(중요하지 않음)
게시판에 적용시킬 디자인요소에 해당하는 css파일을 작성.
WebContent/boardone/css/style.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 |
@CHARSET "UTF-8";
body{
background-color:#d1d3fc;
font-size:15px;
color: #ce16e9;
text-align: center;
}
a:link {
text-decoration:nonecolor:#696969;
}
a:hover{
text-decoration:yescolor:#66ccff;
}
a:visited {
text-decoration:noncolor:#330066;
}
|
cs |
기본적인 게시판작성 준비 완료
이제 본격적으로 게시판을 구현하도록 한다.
먼저 게시판에 글을 작성할 수 있는 글쓰기 화면을 작성한다.
WebContent/boardone/writeForm.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 |
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!doctype html>
<html>
<head>
<title>My Board</title>
<link href="css/style.css" rel="stylesheet" type="text/css"/>
<link href="css/writeFormstyle.css" rel="stylesheet" type="text/css"/>
<script src="script.js"></script>
</head>
<!-- //뒤에서 새글, 답변글 구분하는 코드를 추가할 부분<1> -->
<body>
<section>
<b>글쓰기</b>
<article>
<form method="post" name="writeForm" action="writeProc.jsp"
onsubmit="return writeSave()">
<table class="board">
<tr>
<td class="attr">이름</td>
<td><input type="text" name="writer"/></td>
</tr>
<tr>
<td class="attr">이메일</td>
<td><input type="email" name="email"/></td>
</tr>
<tr>
<td class="attr">제목</td>
<td><input class="input" type="text" name="subject"/></td>
</tr>
<tr>
<td class="attr">내용</td>
<td>
<textarea name="content" rows="13" cols="50"></textarea>
</td>
</tr>
<tr>
<td class="attr">비밀번호</td>
<td><input type="password" name="pass"/></td>
</tr>
<tr>
<td colspan="2" class="attr">
<input type="submit" value="글쓰기"/>
<input type="reset" value="다시 작성"/>
<input type="button" value="목록"
onClick="window.location='list.jsp'">
</td>
</tr>
</table>
</form>
</article>
</section>
<!-- 예외처리 코드가 들어갈 부분<2> -->
</body>
</html> |
cs |
-CSS작성
WebContent/boardone/css/writeFormstyle.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 |
@CHARSET "UTF-8";
section{
padding-top: 30px;
width:500px;
margin: auto;
left:0; top:0; right:0; bottom:0;
}
.board{
text-align:center;
border-collapse:collapse;
}
.board td {
border:1px solid #333;
text-align:left;
width:200px;
height:30px;
border:1px solid #333;
}
.board td .input{
width:97%;
}
.board .attr{
width: 100px;
text-align:center;
} |
cs |
작성 후 실행하면 다음과 같은 페이지가 보여진다.
확인 후 writeSave() 함수를 자바스크립트로 작성해야 한다.
WebContent/boardone/script.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 |
function writeSave(){
if(document.writeForm.writer.value == ""){
alert("작성자를 입력하세요.");
document.writeForm.writer.focus();
return false;
}
if(document.writeForm.subject.value == ""){
alert("제목을 입력하세요.");
document.writeForm.subject.focus();
return false;
}
if(document.writeForm.content.value == ""){
alert("내용을 입력하세요.");
document.writeForm.content.focus();
return false;
}
if(document.writeForm.pass.value == ""){
alert("비밀번호를 입력하세요.");
document.writeForm.pass.focus();
return false;
}
}
|
cs |
작성 후 writeForm.jsp를 실행하여 글쓰기 버튼을 눌러 값을 확인하는 동작을 확인한다.
다음으로 글 작성 기능을 구현한다.
글쓰기 버튼을 클릭 했을 때 writeProc.jsp페이지로 이동하여 글쓰기 기능을 수행할 것이다. 이 때 새글 및 답글을 구분하기 위해 writeForm.jsp파일의 주석<1> 부분에 다음 코드를 추가한다.
WebContent/boardone/writeForm.jsp 의 <1>주석 부분에 추가
1
2
3
4
5
6
7
8
9
10
11
12
13 |
<%
int num = 0;
int ref = 1;
int step = 0;
int depth = 0;
try{
if(request.getParameter("num") != null){
num = Integer.parseInt(request.getParameter("num"));
ref = Integer.parseInt(request.getParameter("ref"));
step = Integer.parseInt(request.getParameter("step"));
depth = Integer.parseInt(request.getParameter("depth"));
}
%> |
cs |
새 글일 경우는 num=0 이라는 값이 넘어가고 답글일 경우 원본 글의 num값을 받아와서 넘기도록 동작한다.
위 코드 작성 후 주석<2>부분에 예외처리 코드를 추가한다.
WebContent/boardone/writeForm.jsp 의 <2>주석 부분에 추가
1
2
3
4 |
<!-- 예외처리 코드가 들어갈 부분<2> -->
<% }catch(Exception e) {
e.printStackTrace();
} %> |
cs |
다음 추가적으로 writeProc.jsp페이지로 이동할 때 num, ref, step, depth의 값을 갖고 넘어가야 하므로 hidden형태로 넘겨주도록 한다.
writeForm.jsp파일의 <form>태그 안에 다음 코드를 추가한다.
1
2
3
4
5 |
<input type="hidden" name="num" value="<%= num %>"/>
<input type="hidden" name="ref" value="<%= ref %>"/>
<input type="hidden" name="step" value="<%= step %>"/>
<input type="hidden" name="depth" value="<%= depth %>"/>
|
cs |
그리고 제목 부분을 구현하고 있는 input태그를 수정하여
새 글과 답 글을 구별할 수 있도록 한다.
writeForm.jsp의 제목을 구현한 부분의 <input> 태그를 다음과 같이 수정
1
2
3
4
5
6
7
8 |
<td class="attr">제목</td>
<td>
<% if(request.getParameter("num") == null) { %>
<input class="input" type="text" name="subject"/>
<%} else { %>
<input class="input" type="text" name="subject" value="[답변]"/>
<%} %>
</td> |
cs |
writeForm.jsp로부터 num, ref, step, level을 받아서 DB에 데이터를 넣어줄 writeProc.jsp를 작성한다.
WebContent/boardone/writeProc.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 |
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import = "boardone.BoardDao" %>
<%@ page import = "java.sql.Timestamp" %>
<% request.setCharacterEncoding("UTF-8"); %>
<jsp:useBean id="article" scope="page" class="boardone.BoardDto">
<jsp:setProperty name="article" property="*"/>
</jsp:useBean>
<%
article.setRegdate( new Timestamp( System.currentTimeMillis() ) );
article.setIp( request.getRemoteAddr() );
BoardDao dbPro = BoardDao.getInstance();
dbPro.insertArticle(article);
response.sendRedirect("list.jsp");
%>
|
cs |
그 다음 insertArticle(BoardDto article) 메서드가 없으므로 BoardDao에 추가한다.
src/boardone/BoardDao.java 파일에 다음 메서드 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 |
public void insertArticle(BoardDto article){
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
int num = article.getNum();
int ref = article.getRef();
int step = article.getStep();
int depth = article.getDepth();
int number = 0;
String sql = "";
try{
conn = ConnUtil.getConnection();
pstmt = conn.prepareStatement("select max(NUM) from BOARD");
rs = pstmt.executeQuery();
if(rs.next()){
number = rs.getInt(1) + 1;
}
else{
number = 1;
}
if(num != 0){ //답 글일 경우
sql = "update BOARD set STEP=STEP+1 where REF = ? and STEP > ?";
pstmt.close();
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, ref);
pstmt.setInt(2, step);
pstmt.executeQuery();
step++;
depth++;
}
else{//새 글일 경우
ref = number;
step = 0;
depth = 0;
}
//쿼리 작성
sql = "insert into BOARD"
+ "(NUM, WRITER, EMAIL, SUBJECT, PASS, "
+ "REGDATE, REF, STEP, DEPTH, CONTENT, IP) "
+ "values(BOARD_SEQ.nextval, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
pstmt.close();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, article.getWriter());
pstmt.setString(2, article.getEmail());
pstmt.setString(3, article.getSubject());
pstmt.setString(4, article.getPass());
pstmt.setTimestamp(5, article.getRegdate());
pstmt.setInt(6, ref);
pstmt.setInt(7, step);
pstmt.setInt(8, depth);
pstmt.setString(9, article.getContent());
pstmt.setString(10, article.getIp());
pstmt.executeQuery();
}catch(Exception e){
e.printStackTrace();
}finally{
if(rs != null) try { rs.close(); } catch (SQLException e){}
if(pstmt != null) try { pstmt.close(); } catch (SQLException e){}
if(conn != null) try { conn.close(); } catch (SQLException e){}
}
} |
cs |
이제 실행해서 글쓰기를 입력하면 DB에 저장은 된다. 저장 후 이동하는 페이지인 list.jsp페이지가 없으므로 글쓰기 후 404에러페이지가 출력되지만 DB의 내용을 확인해보면 글 내용이 저장되는 것을 확인할 수 있다.
DB에 저장된 데이터 확인
그래서 글 목록을 확인할 수 있는 페이지를 작성한다.
먼저 글의 개수를 가져올 메서드를 BoardDao.java에 추가한다.
BoardDao.java에 다음 메서드 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 |
public int getArticleCount(){
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
int x = 0;
try{
conn = ConnUtil.getConnection();
pstmt = conn.prepareStatement("select count(*) from BOARD");
rs = pstmt.executeQuery();
if(rs.next()){
x = rs.getInt(1);
}
} catch(Exception e){
e.printStackTrace();
} finally{
if(rs != null) try { rs.close(); } catch (SQLException e){}
if(pstmt != null) try { pstmt.close(); } catch (SQLException e){}
if(conn != null) try { conn.close(); } catch (SQLException e){}
}
return x;
} |
cs |
다음은 데이터베이스의 board table에서 데이터를 가져오는 메서드를 BoardDao.java에 추가한다.
src/boardone/BoardDao.java 파일에 추가
먼저 맨 윗줄에 import java.util.*; 추가 후 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 |
public List<BoardDto> getArticles(/* 수정<1> */){
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
List<BoardDto> articleList = null;
try{
conn = ConnUtil.getConnection();
/* 수정<2> */
pstmt = conn.prepareStatement(
"select * from BOARD order by NUM desc"); //수정<3>
rs = pstmt.executeQuery();
if(rs.next()){
articleList = new ArrayList<BoardDto>(); //수정<4>
do {
BoardDto article = new BoardDto();
article.setNum(rs.getInt("num"));
article.setWriter(rs.getString("writer"));
article.setEmail(rs.getString("email"));
article.setSubject(rs.getString("subject"));
article.setPass(rs.getString("pass"));
article.setRegdate(rs.getTimestamp("regdate"));
article.setReadcount(rs.getInt("readcount"));
article.setRef(rs.getInt("ref"));
article.setStep(rs.getInt("step"));
article.setDepth(rs.getInt("depth"));
article.setContent(rs.getString("content"));
article.setIp(rs.getString("ip"));
articleList.add(article);
} while(rs.next());
}
} catch(Exception e){
e.printStackTrace();
} finally{
if(rs != null) try { rs.close(); } catch (SQLException e){}
if(pstmt != null) try { pstmt.close(); } catch (SQLException e){}
if(conn != null) try { conn.close(); } catch (SQLException e){}
}
return articleList;
}
|
cs |
실제로 글목록을 보여줄 list.jsp 페이지를 작성한다.
WebContent/boardone/list.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83 |
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import = "boardone.BoardDao" %>
<%@ page import = "boardone.BoardDto" %>
<%@ page import = "java.util.List" %>
<%@ page import = "java.text.SimpleDateFormat" %>
<%!
//수정<1>
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
%>
<%
//수정<2>
int count = 0;
int number = 0;
List<BoardDto> articleList = null;
BoardDao dbPro = BoardDao.getInstance();
count = dbPro.getArticleCount(); //전체 글 수
if(count > 0){
articleList = dbPro.getArticles(); //수정<3>
}
number = count; //수정<4>
%>
<!doctype html>
<html>
<head>
<title>게시판</title>
<link href="css/style.css" rel="stylesheet" type="text/css">
<link href="css/liststyle.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<section>
<article>
<b>글목록(전체 글:<%= count %>)</b>
<table class="listwritebutton">
<tr>
<td><a href="writeForm.jsp">글쓰기</a></td>
<tr>
</table>
<%
if(count == 0){
%>
<table class="listtable">
<tr>
<td>게시판에 저장된 글이 없습니다.</td>
</table>
<% } else { %>
<table class="listtable">
<tr>
<th id="num">번 호</th>
<th id="title">제 목</th>
<th id="writer">작성자</th>
<th id="date">작성일</th>
<th id="counter">조 회</th>
<th id="ip">IP</th>
</tr>
<%
for(int i = 0; i < articleList.size(); i++){
BoardDto article = (BoardDto)articleList.get(i);
%>
<tr>
<td> <%= number-- %></td>
<td class="titletd">
<!-- 수정<5> -->
<a href="content.jsp?num=<%= article.getNum() %>&pageNum=1"><!-- 수정<6> -->
<%= article.getSubject() %></a>
<% if(article.getReadcount() >= 20){ %>
<img src="images/hot.gif"><% } %></td>
<td>
<a href="mailto:<%= article.getEmail() %>">
<%= article.getWriter() %></a></td>
<td>
<%= sdf.format(article.getRegdate()) %></td>
<td><%= article.getReadcount() %></td>
<td><%= article.getIp() %></td>
</tr>
<% } %>
</table>
</article>
<% } %>
<!-- 수정<7> -->
</section>
</body>
</html> |
cs |
-CSS작성
WebContent/boardone/css/liststyle.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 |
@CHARSET "UTF-8";
section{
padding-top: 30px;
width: 700px;
margin: auto;
left:0; top:0; right:0; bottom:0;
}
table{
width:700px;
border-collapse:collapse;
}
a{
text-decoration:none;
}
.listwritebutton{
text-align:right;
}
.listtable{
text-align:center;
border:1px solid #333;
}
.listtable td{
border:1px solid #333;
}
.listtable th{
color: #ffffff;
border:1px solid #333;
background-color: #4aa8b5;
height:30px;
}
.listtable .titletd{
text-align:left;
}
#num{ width:50px;}
#title{ width:250px;}
#writer{ width:100px;}
#date{ width:150px;}
#counter{ width:50px;}
#ip{ width:100px;} |
cs |
요청결과>
위와 같이 앞에서 글을 저장했던 목록이 나오면 DB에서 직접 삭제한다.
(아직 웹 페이지에서 삭제 기능은 동작 불가)
이 후 list.jsp를 실행해서 다음과 같이 “게시판에 저장된 글이 없습니다.” 라는 내용을 확인한다.
다음으로 글 내용을 확인하는 페이지를 작성한다.
list.jsp페이지에서 글 제목을 클릭하면 글의 내용을 보여줄 수 있도록 작업할 것이다.
클릭을 했을 때 해당 글의 num을 매개변수로 DB에서 세부정보를 가져와야 된다.
그래서 DB에서 글 하나의 정보를 가져오는 메서드를 BoardDao.java 에 추가한다.
src/boardone/BoardDao.java 파일에 다음 메서드 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 |
public BoardDto getArticle(int num){
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
BoardDto article = null;
try{
conn = ConnUtil.getConnection();
pstmt = conn.prepareStatement(
"update BOARD set READCOUNT=READCOUNT+1 where NUM = ?");
pstmt.setInt(1, num);
pstmt.executeQuery();
pstmt.close();
pstmt = conn.prepareStatement("select * from BOARD where NUM = ?");
pstmt.setInt(1, num);
rs = pstmt.executeQuery();
if(rs.next()){
article = new BoardDto();
article.setNum(rs.getInt("num"));
article.setWriter(rs.getString("writer"));
article.setEmail(rs.getString("email"));
article.setSubject(rs.getString("subject"));
article.setPass(rs.getString("pass"));
article.setRegdate(rs.getTimestamp("regdate"));
article.setReadcount(rs.getInt("readcount"));
article.setRef(rs.getInt("ref"));
article.setStep(rs.getInt("step"));
article.setDepth(rs.getInt("depth"));
article.setContent(rs.getString("content"));
article.setIp(rs.getString("ip"));
}
} catch(Exception e){
e.printStackTrace();
} finally{
if(rs != null) try { rs.close(); } catch (SQLException e){}
if(pstmt != null) try { pstmt.close(); } catch (SQLException e){}
if(conn != null) try { conn.close(); } catch (SQLException e){}
}
return article;
} |
cs |
다음으로 글 내용을 보여줄 content.jsp를 작성한다.
WebContent/boardone/content.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 |
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import = "boardone.BoardDao" %>
<%@ page import = "boardone.BoardDto" %>
<%@ page import = "java.text.SimpleDateFormat" %>
<!doctype html>
<html>
<head>
<title>게시판</title>
<link href="css/style.css" rel="stylesheet" type="text/css">
<link href="css/contentstyle.css" rel="stylesheet" type="text/css">
</head>
<%
int num = Integer.parseInt(request.getParameter("num"));
String pageNum = request.getParameter("pageNum");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
try{
BoardDao dbPro = BoardDao.getInstance();
BoardDto article = dbPro.getArticle(num);
int ref = article.getRef();
int step = article.getStep();
int depth = article.getDepth();
%>
<body>
<section>
<article>
<b>글 내용 보기</b>
<br/><br/>
<form>
<table class="contenttable">
<tr>
<th>글번호</th>
<td><%= article.getNum() %></td>
<th>조회수</th>
<td><%= article.getReadcount() %></td>
</tr>
<tr>
<th>작성자</th>
<td><%= article.getWriter() %></td>
<th>작성일</th>
<td><%= article.getRegdate() %></td>
</tr>
<tr>
<th>글제목</th>
<td colspan="3" class="contenttitle"><%= article.getSubject() %></td>
</tr>
<tr>
<th>글내용</th>
<td colspan="3" class="content"><pre><%= article.getContent() %></pre></td>
</tr>
<tr>
<td colspan="4">
<input type="button" value="글수정"
onClick="document.location.href=
'updateForm.jsp?num=<%=article.getNum()%>&pageNum=<%=pageNum%>'">
<input type="button" value="글삭제"
onClick="document.location.href=
'deleteForm.jsp?num=<%=article.getNum()%>&pageNum=<%=pageNum%>'">
<!-- 수정<1> -->
<input type="button" value="글목록"
onClick="document.location.href=
'list.jsp?pageNum=<%=pageNum%>'">
</td>
</tr>
</table>
<%
} catch(Exception e){}
%>
</form>
</article>
</section>
</body>
</html> |
cs |
- CSS 작성
WebContent/boardone/css/contentstyle.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 |
@CHARSET "UTF-8";
section{
padding-top: 30px;
width:500px;
margin: auto;
left:0; top:0; right:0; bottom:0;
}
.contenttable{
text-align:center;
border-collapse:collapse;
}
.contenttable th{
color: #ffffff;
border:1px solid #333;
background-color: #4aa8b5;
height:30px;
width:125px;
}
.contenttable td {
border:1px solid #333;
text-align:center;
width:125px;
height:30px;
border:1px solid #333;
}
table .contenttitle{
text-align:left;
}
table .content{
text-align:left;
height:200px;
} |
cs |
이제 글 작성하고 저장하고 목록확인 내용확인이 잘 동작하는지 확인한다.
<글 작성하기>
<글 목록확인>
<글 내용확인>
잘 동작하는 것을 확인하면 다음으로 글 수정, 삭제, 답변 처리를 구현한다.
[글수정]을 누를 경우 updateForm.jsp로 이동하도록 링크를 걸었으니 글 수정화면을 작성해야 한다.
글 수정 시에는 목록보기와 다르게 조회 수를 증가시킬 필요가 없기 때문에 num에 해당하는 게시물을 가져오기만 하는 메서드를 BoardDao.java 파일에 추가한다.
src/boardone/BoardDao.java에 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 |
public BoardDto updateGetArticle(int num){
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
BoardDto article = null;
try{
conn = ConnUtil.getConnection();
pstmt = conn.prepareStatement("select * from BOARD where NUM = ?");
pstmt.setInt(1, num);
rs = pstmt.executeQuery();
if(rs.next()){
article = new BoardDto();
article.setNum(rs.getInt("num"));
article.setWriter(rs.getString("writer"));
article.setEmail(rs.getString("email"));
article.setSubject(rs.getString("subject"));
article.setPass(rs.getString("pass"));
article.setRegdate(rs.getTimestamp("regdate"));
article.setReadcount(rs.getInt("readcount"));
article.setRef(rs.getInt("ref"));
article.setStep(rs.getInt("step"));
article.setDepth(rs.getInt("depth"));
article.setContent(rs.getString("content"));
article.setIp(rs.getString("ip"));
}
} catch(Exception e){
e.printStackTrace();
} finally{
if(rs != null) try { rs.close(); } catch (SQLException e){}
if(pstmt != null) try { pstmt.close(); } catch (SQLException e){}
if(conn != null) try { conn.close(); } catch (SQLException e){}
}
return article;
} |
cs |
이어서 updateForm.jsp를 작성한다.
WebContent/boardone/updateForm.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 |
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import = "boardone.BoardDao" %>
<%@ page import = "boardone.BoardDto" %>
<%
int num = Integer.parseInt(request.getParameter("num"));
String pageNum = request.getParameter("pageNum");
try{
BoardDao dbPro = BoardDao.getInstance();
BoardDto article = dbPro.updateGetArticle(num);
%>
<!doctype html>
<html>
<head>
<title>My Board</title>
<link href="css/style.css" rel="stylesheet" type="text/css"/>
<link href="css/writeFormstyle.css" rel="stylesheet" type="text/css"/>
<script src="script.js"></script>
</head>
<body>
<section>
<b>글수정</b>
<article>
<form method="post" name="writeForm"
action="updateProc.jsp?num=<%=num%>&pageNum=<%=pageNum%>"
onsubmit="return writeSave()">
<input type="hidden" name="writer" value="<%=article.getWriter() %>">
<table class="board">
<tr>
<td class="attr">이름</td>
<td><%= article.getWriter() %></td>
</tr>
<tr>
<td class="attr">이메일</td>
<td><input type="email" name="email"
value="<%=article.getEmail()%>"/></td>
</tr>
<tr>
<td class="attr">제목</td>
<td>
<input class="input" type="text" name="subject"
value="<%=article.getSubject() %>"/>
</td>
</tr>
<tr>
<td class="attr">내용</td>
<td>
<textarea name="content" rows="13" cols="50"><%=article.getContent()%>
</textarea>
</td>
</tr>
<tr>
<td class="attr">비밀번호</td>
<td><input type="password" name="pass"/></td>
</tr>
<tr>
<td colspan="2" class="attr">
<input type="submit" value="글수정"/>
<input type="reset" value="다시 작성"/>
<input type="button" value="목록"
onClick="window.location='list.jsp'">
</td>
</tr>
</table>
</form>
</article>
</section>
<!-- 예외처리 코드가 들어갈 부분<2> -->
<% }catch(Exception e) {
e.printStackTrace();
} %>
</body>
</html> |
cs |
글 수정 눌렀을 때 화면
updateForm.jsp에서 비밀번호를 입력한 후 글 수정을 클릭하면 DB의 게시물이 수정되어야 한다. 그래서 BoardDao.java에 글 수정을 처리할 메서드를 추가한다.
src/boardone/BoardDao.java에 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 |
public int updateArticle(BoardDto article){
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String dbpassword = "";
String sql = "";
int result = -1; //결과 값
try{
conn = ConnUtil.getConnection();
pstmt = conn.prepareStatement("select PASS from BOARD where NUM = ?");
pstmt.setInt(1, article.getNum());
rs = pstmt.executeQuery();
if(rs.next()){
dbpassword = rs.getString("pass");//비밀번호 비교
if(dbpassword.equals(article.getPass())){
sql = "update BOARD set WRITER=?,EMAIL=?,"
+ "SUBJECT=?,CONTENT=? where NUM=?";
pstmt.close();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, article.getWriter());
pstmt.setString(2, article.getEmail());
pstmt.setString(3, article.getSubject());
pstmt.setString(4, article.getContent());
pstmt.setInt(5, article.getNum());
pstmt.executeQuery();
result = 1; //수정 성공
} else {
result = 0; //수정 실패
}
}
} catch(Exception e){
e.printStackTrace();
} finally{
if(rs != null) try { rs.close(); } catch (SQLException e){}
if(pstmt != null) try { pstmt.close(); } catch (SQLException e){}
if(conn != null) try { conn.close(); } catch (SQLException e){}
}
return result;
} |
cs |
위의 메서드를 사용하여 수정처리를 해주는 updateProc.jsp페이지를 작성한다.
WebContent/boardone/updateProc.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 |
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import = "boardone.BoardDao" %>
<%@ page import = "java.sql.Timestamp" %>
<% request.setCharacterEncoding("UTF-8"); %>
<jsp:useBean id="article" scope="page" class="boardone.BoardDto">
<jsp:setProperty name="article" property="*"/>
</jsp:useBean>
<%
String pageNum = request.getParameter("pageNum");
BoardDao dbProc = BoardDao.getInstance();
int check = dbProc.updateArticle(article);
if(check == 1){
%>
<meta http-equiv="Refresh" content="0;url=list.jsp?pageNum=<%= pageNum %>">
<% } else { %>
<script>
<!--
alert("비밀번호가 맞지 않습니다.");
history.go(-1);
-->
</script>
<% } %> |
cs |
수정하는 동작에 필요한 작업을 완료했다. 수정이 정상적으로 동작하는지 테스트 한다. 입력되어 있던 내용을 수정해보자. 에러 없이 동작된다면 다음으로 글 삭제를 구현하자.
비밀번호가 다를 경우 팝업 표시
비밀번호 입력 검증
비밀번호를 제대로 입력하면 글 내용이 수정되는 것을 확인할 수 있다.
수정된 결과
글 삭제 버튼을 누르면 비밀번호를 입력 받아 DB의 비밀번호와 비교 후 일치할 경우만 삭제처리를 수행한다. 그리고 비밀번호가 맞지 않을 경우는 메시지 처리만 해준다.
글 삭제화면 작성
WebContent/boardone/deleteForm.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 |
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
int num = Integer.parseInt(request.getParameter("num"));
String pageNum = request.getParameter("pageNum");
%>
<html>
<head>
<title>게시판</title>
<link href="css/style.css" rel="stylesheet" type="text/css">
<link href="css/deleteFormstyle.css" rel="stylesheet" type="text/css"/>
<script>
function deleteSave(){
if(document.delForm.pass.value == ""){
alert("비밀번호를 입력하세요.");
document.delForm.pass.focus();
return false;
}
}
</script>
</head>
<body>
<section>
<b>글삭제</b>
<form method="post" name="delForm" action=
"deleteProc.jsp?pageNum=<%=pageNum%>" onsubmit="return deleteSave()">
<table class="deletetable">
<tr>
<th><b>비밀번호를 입력 해 주세요.</b></th>
</tr>
<tr>
<td>비밀번호 :
<input type="password" name="pass">
<input type="hidden" name="num" value="<%=num%>">
</td>
</tr>
<tr>
<td>
<input type="submit" value="글삭제">
<input type="button" value="글목록" onClick=
"document.location.href='list.jsp?pageNum=<%=pageNum%>'">
</td>
</tr>
</table>
</form>
</section>
</body>
</html> |
cs |
- CSS 작성
WebContent/boardone/css/deleteFormstyle.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 |
@CHARSET "UTF-8";
section{
padding-top: 30px;
width:300px;
margin: auto;
left:0; top:0; right:0; bottom:0;
}
table{
text-align:center;
border-collapse:collapse;
}
th{
color: #ffffff;
border:1px solid #333;
background-color: #4aa8b5;
height:30px;
}
td {
border:1px solid #333;
text-align:center;
width:300px;
height:30px;
border:1px solid #333;
}
|
cs |
이제 글 삭제를 누르면 비밀번호를 입력하도록 동작한다.
비밀번호를 입력하면 DB와 비밀번호를 비교한 후 삭제를 처리할 메서드를 작성한다.
src/boardone/BoardDao.java에 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 |
public int deleteArticle(int num, String pass){
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String dbpasswd = "";
int result = -1; //결과 값
try{
conn = ConnUtil.getConnection();
pstmt = conn.prepareStatement(
"select PASS from BOARD where NUM=?");
pstmt.setInt(1, num);
rs = pstmt.executeQuery();
if(rs.next()){
dbpasswd = rs.getString("pass");
if(dbpasswd.equals(pass)){
pstmt.close();
pstmt = conn.prepareStatement("delete from BOARD where NUM=?");
pstmt.setInt(1, num);
pstmt.executeQuery();
result = 1; //글삭제 성공
} else {
result = 0; //비밀번호 틀림
}
}
}catch(Exception e){
e.printStackTrace();
} finally{
if(rs != null) try { rs.close(); } catch (SQLException e){}
if(pstmt != null) try { pstmt.close(); } catch (SQLException e){}
if(conn != null) try { conn.close(); } catch (SQLException e){}
}
return result;
} |
cs |
이어 삭제를 수행하는 deleteProc.jsp를 작성한다.
WebContent/boardone/deleteProc.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 |
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import = "boardone.BoardDao" %>
<%@ page import = "java.sql.Timestamp" %>
<% request.setCharacterEncoding("UTF-8"); %>
<%
int num = Integer.parseInt(request.getParameter("num"));
String pageNum = request.getParameter("pageNum");
String pass = request.getParameter("pass");
BoardDao dbPro = BoardDao.getInstance();
int check = dbPro.deleteArticle(num, pass);
if(check == 1){
%>
<meta http-equiv="Refresh" content="0;url=list.jsp?pageNum=<%=pageNum%>">
<% } else {%>
<script>
alert("비밀번호가 맞지 않습니다.");
history.go(-1);
</script>
<% } %> |
cs |
완료되면 글 삭제가 이루어지는지 테스트 한다.
삭제 후 보여지는 목록
반응형
'교육자료 > JSP' 카테고리의 다른 글
쿠키개념 이해하기 (0) | 2018.09.03 |
---|---|
(교육자료)게시판에 페이징 처리 및 답글 기능 구현하기 실습 (0) | 2018.09.03 |
(교육자료)Connection Pool 기능 추가하기 (0) | 2018.09.03 |
(교육자료)로그인 기능 구현하기 실습 (0) | 2018.09.03 |
(교육자료)회원가입 기능 구현하기 실습 (0) | 2018.09.03 |