반응형

MVC2 개념을 적용하여 게시판 구현하기

 

1.     데이터베이스 테이블 만들기

앞에서 만든 테이블과 시퀀스 그대로 사용해도 무관

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CREATE table "BOARD" (
    "NUM"        NUMBER(7,0NOT NULL,
    "WRITER"     VARCHAR2(12NOT NULL,
    "EMAIL"      VARCHAR2(30NOT NULL,
    "SUBJECT"    VARCHAR2(50NOT NULL,
    "PASS"       VARCHAR2(10NOT NULL,
    "READCOUNT"  NUMBER(5,0DEFAULT 0 NOT NULL,
    "REF"        NUMBER(5,0DEFAULT 0 NOT NULL,
    "STEP"       NUMBER(3,0DEFAULT 0 NOT NULL,
    "DEPTH"      NUMBER(3,0DEFAULT 0 NOT NULL,
    "REGDATE"    TIMESTAMP DEFAULT SYSDATE NOT NULL,
    "CONTENT"    VARCHAR2(4000NOT NULL,
    "IP"         VARCHAR2(20NOT NULL,
    constraint  "BOARD_PK" primary key ("NUM")
);
cs

다음 시퀀스 생성
1
2
3
4
5
6
CREATE SEQUENCE BOARD_SEQ
    START WITH 1
    INCREMENT BY 1
    NOMAXVALUE
    NOCACHE
    NOCYCLE;
cs


2.     MVC패턴에서 모델에 해당하는 부분(Dto, Dao)을 작성한다.

src/boardtwo/model/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
package boardtwo.model;
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 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

3.     Connection Pool을 사용하기 위한 설정 적용

WebContent/META-INF/Context.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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="scott"
                password="tiger"
                initialSize="50"
                maxActive="20"
                maxIdle="10"
                maxWaitMillis="-1"/>
</Context>
cs

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

DB 커넥션을 관리하는 Connection Pool을 사용할 수 있도록 ConnUtil클래스 작성
src/boardtwo/model/ConnUtil.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package boardtwo.model;
 
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/boardtwo/model/BoardDao.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package boardtwo.model;
 
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


4.  컨트롤러와 명령어를 처리하는 슈퍼 인터페이스 작성


         A. 령어와 명령어 처리 클래스를 매핑한 정보파일 작성

/WebContent/WEB-INF/CommandPro.properties

1
2
3
4
5
6
7
8
/board/list.do=boardtwo.action.ListAction
/board/writeForm.do=boardtwo.action.WriteFormAction
/board/writePro.do=boardtwo.action.WriteProAction
/board/content.do=boardtwo.action.ContentAction
/board/updateForm.do=boardtwo.action.UpdateFormAction
/board/updatePro.do=boardtwo.action.UpdateProAction
/board/deleteForm.do=boardtwo.action.DeleteFormAction
/board/deletePro.do=boardtwo.action.DeleteProAction
cs


B.명령어를 처리하는 슈퍼 인터페이스 작성

 게시판에 들어오는 요청의 개수만큼 만들도록 한다.

메서드

설명

CommandAction

컨트롤러인 서블릿으로부터 명령어를 처리하는 클래스로 가기 위한 단일 진입점 역할을 하는 슈퍼 인터페이스

ListAction

글 목록보기 명령어를 처리하는 클래스

WriteFormAction

클 쓰기 폼 명령을 처리하는 클래스

WriteProAction

글 저장 명령을 처리하는 클래스

ContentAction

글 내용보기 명령을 처리하는 클래스

UpdateFormAction

글 수정 폼 명령을 처리하는 클래스

UpdateProAction

수정한 글의 저장 명령을 처리하는 클래스

DeleteFormAction

글 삭제 폼 명령을 처리하는 클래스

DeleteProAction

글 삭제 명령을 처리하는 클래스


C. 명령어를 처리하는 슈퍼 인터페이스

src/boardtwo/action/CommandAction.java

1
2
3
4
5
6
7
8
9
package boardtwo.action;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public interface CommandAction {
    public String requestPro(HttpServletRequest request, 
            HttpServletResponse response) throws Throwable;
}
cs



D. 컨트롤러 작성

src/boardtwo/controller/ControllerAction.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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package boardtwo.controller;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
 
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import boardtwo.action.CommandAction;
 
public class ControllerAction extends HttpServlet{
 
    private static final long serialVersionUID = 1L;
 
    //명령어와 명령어 처리 클래스를 쌍으로 저장해두는 MAP
    private Map<String, Object> commandMap = 
            new HashMap<String, Object>();
    /*
     * 명령어와 처리클래스가 매핑되어 있는 
     * properties파일(CommandPro.properties)을 읽어
     * Map객체인 commandMap에 저장한다.
     */
    
    //web.xml에서 propertyConfig에 해당하는 init-param의 값을 읽어온다.
    public void init(ServletConfig config) throws ServletException{
        String props = config.getInitParameter("propertyConfig");
        
        //명령어와 커리클래스의 매핑 정보를 저장할 Properties객체 생성
        Properties pr = new Properties();
        FileInputStream f = null;
        String path = config.getServletContext().getRealPath("/WEB-INF");
        try{
            f = new FileInputStream(new File(path, props));
            
            //Command.properties파일의 정보를 Properties객체에 저장
            pr.load(f);
        } catch(IOException e){
            throw new ServletException(e);
        } finally{
            if(f != nulltry{ f.close(); } catch (IOException e){}
        }
        
        //Iterator 객체사용
        Iterator<Object> keyIter = pr.keySet().iterator();
        
        while(keyIter.hasNext()){
            String command = (String)keyIter.next();
            String className = pr.getProperty(command);
            try{
                //가져온 문자열을 클래스로 만듬
                Class<?> commandClass = Class.forName(className);
                
                //만들어진 해당 클래스의 객체 생성
                Object commandInstance = 
                        commandClass.newInstance(); 
                
                //생성된 객체를 commandMap에 저장
                commandMap.put(command, commandInstance);
            } catch(ClassNotFoundException e){
                throw new ServletException(e);
            } catch(InstantiationException e){
                throw new ServletException(e);
            } catch(IllegalAccessException e){
                throw new ServletException(e);
            }
        }
    }
    
    //Get방식 서비스 메서드
    public void doGet(
            HttpServletRequest request, 
            HttpServletResponse response) 
                    throws ServletException, IOException{
        requestPro(request, response);
    }
    
    //Post방식 서비스 메서드
    public void doPost(
            HttpServletRequest request, 
            HttpServletResponse response) 
                    throws ServletException, IOException{
        requestPro(request, response);
    }
    
    //사용자의 요청에 따라 분석하여 해당 작업을 처리
    private void requestPro(
            HttpServletRequest request,
            HttpServletResponse response)
                    throws ServletException, IOException{
        String view = null;
        CommandAction com = null;
        try{
            String command = request.getRequestURI();
            if(command.indexOf(request.getContextPath()) == 0){
                command = command.substring(
                        request.getContextPath().length());
            }
            com = (CommandAction)commandMap.get(command);
            view = com.requestPro(request, response);
        } catch(Throwable e){
            throw new ServletException(e);
        }
        RequestDispatcher dispatcher = 
                request.getRequestDispatcher(view);
        dispatcher.forward(request, response);
    }
}
cs



E. 사용할 web.xml 파일에 다음 내용 추가

WAS에 컨트롤러 서블릿 정보를 등록하고 초기화 파라미터로 명령어 파일을 사용할 수 있도록 지정

서블릿 매핑 정보를 등록하여 *.do로 들어오는 요청을 지정된 컨트롤러가 받도록 설정

1
2
3
4
5
6
7
8
9
10
11
12
<servlet>
      <servlet-name>Controller</servlet-name>
      <servlet-class>boardtwo.controller.ControllerAction</servlet-class>
    <init-param>
        <param-name>propertyConfig</param-name>
        <param-value>commandPro.properties</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
      <servlet-name>Controller</servlet-name>
      <url-pattern>*.do</url-pattern>
</servlet-mapping>
cs



MVC2 게시판 구조


게시판 글 목록보기 구조


전체 글 개수를 알아오는 메서드를 BoardDao에 추가

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//전체 글 개수를 알아오는 메서드
public int getArticleCount(){
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    int count = 0;
    try{
        conn = ConnUtil.getConnection();
        pstmt = conn.prepareStatement("select count(*) from BOARD");
        rs = pstmt.executeQuery();
        if(rs.next()){
            count = rs.getInt(1);
        }
    } catch(Exception ex){
            ex.printStackTrace();
    } finally{
        if(rs != nulltry{rs.close(); } catch(SQLException e){}
        if(pstmt != nulltry{pstmt.close(); } catch(SQLException e){}
        if(conn != nulltry{conn.close(); } catch(SQLException e){}
    }
    return count;
}
cs


BoardDao에 글 목록을 얻어와서 List형태로 리턴해 줄 메서드를 아래와 같이 추가

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
91
92
93
package boardtwo.model;
 
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
 
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;
    }
    //이제부터 여기에 게시판에서 필요한 작업 기능들을 메서드로 추가하게 된다.
    
    //전체 글 개수를 알아오는 메서드
    public int getArticleCount(){
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        int count = 0;
        try{
            conn = ConnUtil.getConnection();
            pstmt = conn.prepareStatement("select count(*) from BOARD");
            rs = pstmt.executeQuery();
            if(rs.next()){
                count = rs.getInt(1);
            }
        } catch(Exception ex){
                ex.printStackTrace();
        } finally{
            if(rs != nulltry{rs.close(); } catch(SQLException e){}
            if(pstmt != nulltry{pstmt.close(); } catch(SQLException e){}
            if(conn != nulltry{conn.close(); } catch(SQLException e){}
        }
        return count;
    }
    //글 목록을 가져와서 List로 반환하는 메서드
    public List<BoardDto> getArticles(int start, int end){
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        List<BoardDto> articleList = null;
        try{
            conn = ConnUtil.getConnection();
            String sql = "select * from "
                + "(select rownum RNUM, NUM, WRITER,"
                + "EMAIL, SUBJECT, PASS, REGDATE,"
                + "READCOUNT, REF, STEP, DEPTH, CONTENT, IP from "
                + "(select * from BOARD order by REF desc, STEP asc)) "
                + "where RNUM >= ? and RNUM <= ?";
            pstmt = conn.prepareStatement(sql);
            System.out.println(sql);
            pstmt.setInt(1, start);
            pstmt.setInt(2, end);
            rs = pstmt.executeQuery();
            if(rs.next()){
                articleList = new ArrayList<BoardDto>(5);
                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 != nulltry { rs.close(); } catch (SQLException e){}
            if(pstmt != nulltry { pstmt.close(); } catch (SQLException e){}
            if(conn != nulltry { conn.close(); } catch (SQLException e){}
        }
        return articleList;
    }
 
}
cs



글 목록을 처리할 클래스를 작성한다.

src/boardtwo/action/ListAction.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
package boardtwo.action;
 
import java.util.Collections;
import java.util.List;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import boardtwo.model.BoardDao;
import boardtwo.model.BoardDto;
 
public class ListAction implements CommandAction{
    public String requestPro (
            HttpServletRequest request,
            HttpServletResponse response)throws Throwable{
        String pageNum = request.getParameter("pageNum"); //페이지 번호
        if(pageNum == null){
            pageNum = "1";
        }
        int pageSize = 5//한 페이지 당 글의 개수
        int currentPage = Integer.parseInt(pageNum);
        //페이지의 시작 글 번호
        
        int startRow = (currentPage - 1* pageSize + 1;
        int endRow = currentPage * pageSize; //한 페이지의 마지막 글 번호
        int count = 0;
        int number = 0;
        List<BoardDto> articleList = null;
        BoardDao dbPro = BoardDao.getInstance(); //DB연결
        count = dbPro.getArticleCount(); //전체 글 개수
        if(count > 0){ //현재 페이지의 글 목록
            articleList = dbPro.getArticles(startRow, endRow);
        } else {
            articleList = Collections.emptyList();
        }
        number = count - (currentPage-1* pageSize; //글 목록에 표시할 글 번호
        
        //해당 뷰에서 사용할 속성
        request.setAttribute("currentPage"new Integer(currentPage));
        request.setAttribute("startRow"new Integer(startRow));
        request.setAttribute("endRow"new Integer(endRow));
        request.setAttribute("count"new Integer(count));
        request.setAttribute("pageSize"new Integer(pageSize));
        request.setAttribute("number"new Integer(number));
        request.setAttribute("articleList", articleList);
 
        return "/boardtwo/list.jsp";    //해당하는 뷰 경로 반환
    }
}
cs



게시판에 사용할 이미지를 다음 경로에 복사하고 CSS를 위한 폴더도 생성

    WebContent/boardtwo/images/ 

    WebContent/boardtwo/css/  



JSTL 태그라이브러리도 추가



기본 CSS 작성

WebContent/boardtwo/css/style.css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@CHARSET "UTF-8";
body{
    background-color:#d1d3fc;
    font-size:15px;
    color: #ce16e9;
    text-align: center;
}
a:link {
    text-decoration:none;
    color:#696969;
}
a:hover{
    text-decoration:none; 
    color:#66ccff;
}
a:visited {
    text-decoration:none;
    color:#330066;
}
cs


결과를 보여줄 뷰를 작성

/WeContent/boardtwo/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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>게시판</title>
<link href="${pageContext.request.contextPath}/resources/css/style.css" rel="stylesheet" type="text/css">
<link href="${pageContext.request.contextPath}/resources/css/liststyle.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<section>
<b>글목록(전체 글:${count})</b>
<table class="listwritebutton">
    <tr>
        <td>
            <a href="${pageContext.request.contextPath}/board/writeForm.do">글쓰기</a>
        </td>
    </tr>
</table>
<c:if test="${count == 0}">
<table  class="listtable">
    <tr>
        <td>
            게시판에 저장된 글이 없습니다.
        </td>
    </tr>
</table>
</c:if>
 
<c:if test="${count > 0}">
<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>
    <c:forEach var="article" items="${articleList}">
    <tr>
        <td align="center" width="50">
            <c:out value="${number}"/>
            <c:set var="number" value="${number - 1}"/>
        </td>
        <td class="titletd">
            <c:if test="${article.depth > 0}">
                <img src="${pageContext.request.contextPath}/resources/images/level.gif"
                    width="${5 * article.depth}">
                <img src="${pageContext.request.contextPath}/resources/images/re.gif">
            </c:if>
            <c:if test="${article.depth == 0}">
                <img src="${pageContext.request.contextPath}/resources/images/level.gif"
                    width="${5 * article.depth}">
            </c:if>
            <a href="${pageContext.request.contextPath}/board/content.do?num=${article.num}&pageNum=${currentPage}">
                ${article.subject}</a>
            <c:if test="${article.readcount >= 20}">
                <img src="${pageContext.request.contextPath}/resources/images/hot.gif">
            </c:if>
        </td>
        <td>
            <a href="mailto:${article.email}">${article.writer}</a>
        </td>
        <td>${article.regdate}</td>
        <td>${article.readcount}</td>
        <td>${article.ip}</td>
    </tr>
    </c:forEach>
</table>
</c:if>
<c:if test="${count > 0}">
    <c:set var="imsi" value="${count % pageSize == 0 ? 0 : 1 }"/>
    <c:set var="pageCount" value="${count / pageSize + imsi }"/>
    <fmt:parseNumber var="pageCount" value="${pageCount}" integerOnly="true"/>
 
    <c:set var="pageBlock" value="${3}"/>
 
    <fmt:parseNumber var="result" value="${(currentPage-1) / pageBlock}" integerOnly="true"/>
    <c:set var="startPage" value="${result * pageBlock + 1 }"/>
 
    <c:set var="endPage" value="${startPage + pageBlock - 1 }"/>
    
    <c:if test="${endPage > pageCount}">
        <c:set var="endPage" value="${pageCount}"/>
    </c:if>
    
    <c:if test="${startPage > pageBlock}">
        <a href="${pageContext.request.contextPath}/board/list.do?pageNum=${startPage - pageBlock }">이전</a>
    </c:if>
    
    <c:forEach var="i" begin="${startPage}" end="${endPage}">
        <a href="${pageContext.request.contextPath}/board/list.do?pageNum=${i}">[${i}]</a>
    </c:forEach>
    
    <c:if test="${endPage < pageCount}">
        <a href="${pageContext.request.contextPath}/board/list.do?pageNum=${startPage + pageBlock }">다음</a>
    </c:if>
</c:if>
</section>
</body>
</html>
cs



CSS작성

WebContent/boardtwo/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


게시판 글쓰기 폼 구조


글 쓰기 요청을 처리할 Action클래스를 정의한다.

src/boardtwo/action/WriteFormAction.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
package boardtwo.action;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class WriteFormAction implements CommandAction{
    public String requestPro( HttpServletRequest request, HttpServletResponse response)
                     throws Throwable {
        //제목글과 답변글의 구분
        int num=0, ref = 1, step=0, 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"));
            }
        } catch (Exception e) { e.printStackTrace(); }
 
        //해당 뷰에서 사용할 속성
        request.setAttribute("num"new Integer(num));
        request.setAttribute("ref"new Integer(ref));
        request.setAttribute("step"new Integer(step));
        request.setAttribute("depth"new Integer(depth));
        return "/boardtwo/writeForm.jsp";    //해당 뷰 경로 반환
    }
}
cs



글 입력 화면에서 입력 내용을 체크할 자바스크립트를 파일로 작성한다.

/WebContent/boardtwo/script.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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



화면에 보여줄 뷰 작성

/WebContent/boardtwo/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
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"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>게시판</title>
<script src="${pageContext.request.contextPath}/boardtwo/script.js"></script>
<link href="${pageContext.request.contextPath}/boardtwo/css/style.css" rel="stylesheet" type="text/css"/>
<link href="${pageContext.request.contextPath}/boardtwo/css/writeFormstyle.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<section>
<article>
<b>글쓰기</b>
<br></br>
<form method="post" name="writeForm" action="${pageContext.request.contextPath}/board/writePro.do"
    onsubmit="return writeSave()">
    <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}">    
 
    <table  class="board">
        <tr>
            <td class="attr">이 름</td>
            <td>
                <input type="text" name="writer">
            </td>
        </tr>
        <tr>
            <td class="attr">E-mail</td>
            <td>
                <input type="email" name="email">
            </td>
        </tr>
        <tr>
            <td class="attr">제 목</td>
            <td>
            <c:if test="${num == 0}">
            <input class="input" type="text" name="subject">
            </c:if>
            <c:if test="${num != 0}">
            <input class="input" type="text" name="subject" value="[답변]"> 
            </c:if>
            </td>
        </tr>
        <tr>
            <td class="attr">내 용</td>
            <td>
                <textarea name="content" rows="13" cols="40"></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='${pageContext.request.contextPath}/board/list.do'">
            </td>
        </tr>
        </table>
</form>
</article>
</section>
</body>
</html>
cs



CSS작성

WebContent/boardtwo/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
26
27
@CHARSET "UTF-8";
section{
    padding-top: 30px;
    width:430px;
    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:330px;    
    height:30px;
    border:1px solid #333;
}
.board td .input{
    width:97%;
}
.board .attr{
    width: 100px;
    text-align:center;
}
cs


게시판 글 저장 구조

글 저장을 처리할 메서드를 Dao에 추가한다.

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
//글 저장을 처리하는 메서드
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.executeUpdate();
            step = step + 1;
            depth = depth + 1;
        } 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 = 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.executeUpdate();
    }catch(Exception e){
        e.printStackTrace();
    }finally{
        if(rs != nulltry { rs.close(); } catch (SQLException e){}
        if(pstmt != nulltry { pstmt.close(); } catch (SQLException e){}
        if(conn != nulltry { conn.close(); } catch (SQLException e){}
    }
}
cs



글 저장을 처리할 Action클래스 작성

src/boardtwo/action/WriteProAction.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
package boardtwo.action;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import java.sql.Timestamp;
 
import boardtwo.model.BoardDao;
import boardtwo.model.BoardDto;
 
public class WriteProAction implements CommandAction{
 
    public String requestPro(
            HttpServletRequest request, 
            HttpServletResponse response) throws Throwable {
        request.setCharacterEncoding("UTF-8");
        BoardDto article = new BoardDto();    //데이터를 처리할 빈
        article.setNum(Integer.parseInt(request.getParameter("num")));
        article.setWriter(request.getParameter("writer"));
        article.setEmail(request.getParameter("email"));
        article.setSubject(request.getParameter("subject"));
        article.setPass(request.getParameter("pass"));
        article.setRegdate(new Timestamp(System.currentTimeMillis()));
        article.setRef(Integer.parseInt(request.getParameter("ref")));
        article.setStep(Integer.parseInt(request.getParameter("step")));
        article.setDepth(Integer.parseInt(request.getParameter("depth")));
        article.setContent(request.getParameter("content"));
        article.setIp(request.getRemoteAddr());
 
        BoardDao dbPro = BoardDao.getInstance(); //DB 연결
        dbPro.insertArticle(article);
        return "/boardtwo/writePro.jsp";    //해당 뷰 경로 반환
    }
}
cs



결과를 보여줄 뷰를 작성해야 되는데 현재는 보여줄 결과가 없으므로 일당 list.jsp페이지로 리다이렉트 한다

/WebContent/boardtwo/writePro.jsp

1
2
3
4
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<meta http-equiv="Refresh"     content="0;url=${pageContext.request.contextPath}/board/list.do">
cs


게시판 글 내용보기 구조

DB에서 글 내용을 가져오는 메서드를 Dao에 추가

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
//글 내용을 가져오는 메서드
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.executeUpdate();
        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 != nulltry { rs.close(); } catch (SQLException e){}
        if(pstmt != nulltry { pstmt.close(); } catch (SQLException e){}
        if(conn != nulltry { conn.close(); } catch (SQLException e){}
    }
    return article;
}
cs


명령어 처리 요청을 처리할 Action클래스 작성

src/boardtwo/action/ContentAction.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
package boardtwo.action;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import boardtwo.model.BoardDao;
import boardtwo.model.BoardDto;
//글 내용을 처리
public class ContentAction implements CommandAction{
    public String requestPro(
            HttpServletRequest request, 
            HttpServletResponse response) throws Throwable {
        
        //해당 글번호
        int num = Integer.parseInt(request.getParameter("num"));
        
        //해당 페이지 번호
        String pageNum = request.getParameter("pageNum");
        BoardDao dbPro = BoardDao.getInstance();
        
        //해당 글번호에 대한 레코드
        BoardDto article = dbPro.getArticle(num);
        
        //뷰에서 사용할 속성
        request.setAttribute("num"new Integer(num));
        request.setAttribute("pageNum"new Integer(pageNum));
        request.setAttribute("article", article);
        return "/boardtwo/content.jsp"//요청에 응답할 뷰 경로
    }
}
cs


요청한 글에 대해 화면에 보여줄 뷰를 작성

/WebContent/boardtwo/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
<%@ 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 http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>게시판</title>
<link href="${pageContext.request.contextPath}/boardtwo/css/style.css" rel="stylesheet" type="text/css">
<link href="${pageContext.request.contextPath}/boardtwo/css/contentstyle.css" rel="stylesheet" type="text/css">
</head>
<body>
<section>
<b>글내용 보기</b>
<br>
<form>
<table  class="contenttable">
    <tr>
        <th>글번호</th>
        <td>${article.num}</td>
        <th>조회수</th>
        <td>${article.readcount}</td>
    </tr>
    <tr>
        <th>작성자</th>
        <td>${article.writer}</td>
        <th>작성일</th>
        <td>${article.regdate}</td>
    </tr>
    <tr>
        <th>글제목</th>
        <td colspan="3" class="contenttitle">${article.subject}</td>
    </tr>
    <tr>
        <th>글내용</th>
        <td colspan="3" class="content">
        <pre>${article.content}</pre></td>
    </tr>
    
    <tr>
        <td colspan="4">
        <input type="button" value="수 정" onClick=
    "document.location.href='${pageContext.request.contextPath}/board/updateForm.do?num=${article.num}&pageNum=${pageNum}'">
            &nbsp;&nbsp;&nbsp;&nbsp;
        <input type="button" value="삭 제" onClick=
"document.location.href='${pageContext.request.contextPath}/board/deleteForm.do?num=${article.num}&pageNum=${pageNum}'">
            &nbsp;&nbsp;&nbsp;&nbsp;
        <input type="button" value="답 글" onClick=
"document.location.href='${pageContext.request.contextPath}/board/writeForm.do?num=${article.num}&ref=${article.ref}&step=${article.step}&depth=${article.depth}'">
            &nbsp;&nbsp;&nbsp;&nbsp;
        <input type="button" value="목 록" onClick=
"document.location.href='${pageContext.request.contextPath}/board/list.do?pageNum=${pageNum}'">
            &nbsp;&nbsp;&nbsp;&nbsp;
    </tr>
</table>
</form>
</section>
</body>
</html>
cs


CSS작성

WebContent/boardtwo/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


글 수정 폼 구조


수정할 글의 정보를 받아오는 메서드를 Dao에 추가

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
//글 수정을 처리할 글의 세부 테이터를 받아올 수 있는 방법
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 != nulltry { rs.close(); } catch (SQLException e){}
        if(pstmt != nulltry { pstmt.close(); } catch (SQLException e){}
        if(conn != nulltry { conn.close(); } catch (SQLException e){}
    }
    return article;
}
cs



수정 요청을 처리할 Action 클래스 작성

src/boardtwo/action/UpdateFormAction.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
package boardtwo.action;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import boardtwo.model.BoardDao;
import boardtwo.model.BoardDto;
 
public class UpdateFormAction implements CommandAction {
 
    public String requestPro(
            HttpServletRequest request,
            HttpServletResponse response) throws Throwable {
        int num = Integer.parseInt(request.getParameter("num"));
        String pageNum = request.getParameter("pageNum");
        BoardDao dbPro = BoardDao.getInstance();
        BoardDto article = dbPro.updateGetArticle(num);
        
        //뷰에서 사용할 속성
        request.setAttribute("pageNum"new Integer(pageNum));
        request.setAttribute("article", article);
 
        return "/boardtwo/updateForm.jsp"//보여줄 뷰 경로
    }
 
}
cs


화면에 보여줄 뷰 작성

/WebContent/boardtwo/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
<%@ 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>
<title>게시판</title>
<script src="${pageContext.request.contextPath}/boardtwo/script.js"></script>
<link href="${pageContext.request.contextPath}/boardtwo/css/style.css" rel="stylesheet" type="text/css"/>
<link href="${pageContext.request.contextPath}/boardtwo/css/writeFormstyle.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<section>
<b>글수정</b>
    <form method="post" name="writeForm" action=
"${pageContext.request.contextPath}/board/updatePro.do?pageNum=${pageNum}" 
    onsubmit="return writeSave()">
        <table class="board">
            <tr>
            <td class="attr">이 름</td>
            <td>${article.writer}
                <input type="hidden" name="num" value="${article.num}">
                <input type="hidden" name="writer" value="${article.writer}">
            </td>
        </tr>
        <tr>
            <td class="attr">E-mail</td>
            <td>
                <input type="text" name="email" value="${article.email}">
            </td>
        </tr>
        <tr>
            <td class="attr">제 목</td>
            <td>
                <input class="input" type="text" name="subject" value="${article.subject}">
            </td>
        </tr>
        <tr>
            <td class="attr">내 용</td>
            <td>
                <textarea name="content" rows="13" cols="50">${article.content}</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='${pageContext.request.contextPath}/board/list.do?pageNum=${pageNum}'">
            </td>
        </tr>
        </table>
    </form>
</section>
</body>
</html>
cs


글 수정 처리 구조

DB에 글 수정을 처리하는 메서드를 Dao에 추가한다.

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
//글 수정 처리할 메서드
public int updateArticle(BoardDto article){
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    String dbpasswd = "";
    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()){
            dbpasswd = rs.getString("pass");
            if(dbpasswd.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.executeUpdate();
                result = 1//수정 성공
            } else {
                result = 0//수정 실패
            }
        }
    } catch (Exception e){
        e.printStackTrace();
    } finally {
        if(rs != nulltry { rs.close(); } catch (SQLException e){}
        if(pstmt != nulltry { pstmt.close(); } catch (SQLException e){}
        if(conn != nulltry { conn.close(); } catch (SQLException e){}
    }
    return result;
}
cs


수정 요청을 처리하는 Action클래스 작성

src/boardtwo/action/UpdateProAction.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
package boardtwo.action;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import boardtwo.model.BoardDao;
import boardtwo.model.BoardDto;
 
public class UpdateProAction implements CommandAction{
 
    public String requestPro(
            HttpServletRequest request, 
            HttpServletResponse response) throws Throwable {
        request.setCharacterEncoding("UTF-8");
        String pageNum = request.getParameter("pageNum");
        
        BoardDto article = new BoardDto();    //데이터를 처리할 빈
        article.setNum(Integer.parseInt(request.getParameter("num")));
        article.setWriter(request.getParameter("writer"));
        article.setEmail(request.getParameter("email"));
        article.setSubject(request.getParameter("subject"));
        article.setPass(request.getParameter("pass"));
        article.setContent(request.getParameter("content"));
 
        
        BoardDao dbPro = BoardDao.getInstance(); //DB 연결
        int check = dbPro.updateArticle(article);
        
        //뷰에 사용할 속성
        request.setAttribute("pageNum"new Integer(pageNum));
        request.setAttribute("check"new Integer(check));
            
        return "/boardtwo/updatePro.jsp";    //해당 뷰 경로 반환
    }
}
cs


다음은 글 삭제 폼 구조


폼으로 삭제요청을 처리할 Action클래스 작성

src/boardtwo/action/DeleteFormAction.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package boardtwo.action;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class DeleteFormAction implements CommandAction{
 
    public String requestPro(
            HttpServletRequest request, 
            HttpServletResponse response) throws Throwable {
        
        int num = Integer.parseInt(request.getParameter("num"));
        String pageNum = request.getParameter("pageNum");
        System.out.println(pageNum);
        
        request.setAttribute("num"new Integer(num));
        request.setAttribute("pageNum"new Integer(pageNum));
        return "/boardtwo/deleteForm.jsp";    //처리할 뷰 경로
    }
}
cs


화면에 보여줄 뷰 작성

/WebContent/boardtwo/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"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<link href="${pageContext.request.contextPath}/boardtwo/css/style.css" rel="stylesheet" type="text/css"/>
<head>
<title>게시판</title>
<script>
    function deleteSave(){
        if(document.delForm.pass.value==""){
            alert("비밀번호를 입력하세요.");
            document.delForm.pass.focus();
            return false;
        }
    }
</script>
<link href="${pageContext.request.contextPath}/boardtwo/css/style.css" rel="stylesheet" type="text/css">
<link href="${pageContext.request.contextPath}/boardtwo/css/deleteFormstyle.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<section>
<b>글삭제</b>
<form method="POST" name="delForm" action=
    "${pageContext.request.contextPath}/board/deletePro.do?pageNum=${pageNum}" 
    onsubmit="return deleteSave()">
    <table class="deletetable">
        <tr>
            <td><b>비밀번호를 입력해 주세요.</b></td>
        </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='${pageContext.request.contextPath}/board/list.do?pageNum=${pageNum}'">
            </td>
        </tr>
    </table>
</form>
</section>
</body>
</html>
 
cs


CSS 작성

WebContent/boardtwo/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
@CHARSET "UTF-8";
section{
    padding-top: 30px;
    width:360px;
    margin: auto;
    left:0; top:0; right:0; bottom:0;
}
.deletetable{
    width: 360px;
    text-align:center;
    border-collapse:collapse;
}
.deletetable th{
    color: #ffffff;
    border:1px solid #333;
    background-color: #4aa8b5; 
    height:30px;
}
.deletetable td {
    border:1px solid #333;
    text-align:center;
    height:30px;
    border:1px solid #333;
}
cs


글 삭제 처리 구조

DB에서 게시글을 삭제하는 기능을 Dao에 추가한다.

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
//DB에서 글을 삭제하는 메서드
public int deleteArticle(int num, String pass){
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    String dbPass = "";
    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()){
            dbPass = rs.getString("pass");
            if(dbPass.equals(pass)){
                pstmt.close();
                pstmt = conn.prepareStatement(
                        "delete from BOARD where NUM = ?");
                pstmt.setInt(1, num);
                pstmt.executeUpdate();
                result = 1//삭제 성공
            } else { result = 0//비밀번호 불일치 }
        }
    } catch (Exception e){
        e.printStackTrace();
    } finally {
        if(rs != nulltry { rs.close(); } catch (SQLException e){}
        if(pstmt != nulltry { pstmt.close(); } catch (SQLException e){}
        if(conn != nulltry { conn.close(); } catch (SQLException e){}
    }
    return result;
}
cs


다음으로 글 삭제 처리요청을 수행하는 Action클래스를 작성한다.

src/boardtwo/action/DeleteProAction.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
package boardtwo.action;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import boardtwo.model.BoardDao;
 
public class DeleteProAction implements CommandAction{
 
    public String requestPro(
            HttpServletRequest request,
            HttpServletResponse response) throws Throwable {
        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);
        
        //뷰에서 사용할 속성
        request.setAttribute("pageNum"new Integer(pageNum));
        request.setAttribute("check"new Integer(check));
 
        return "/boardtwo/deletePro.jsp"//뷰 경로
    }
}
cs


화면에 보여줄 뷰 페이지를 작성

/WebContent/boardtwo/deletePro.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"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
 
<c:if test="${check == 1}">
    <meta http-equiv="Refresh" content=
    "0;url=${pageContext.request.contextPath}/board/list.do?pageNum=${pageNum}">
</c:if>
<c:if test="${check == 0}">
<!doctype html>
<html>
<head>
<link href="${pageContext.request.contextPath}/boardtwo/css/style.css" rel="stylesheet" type="text/css">
<link href="${pageContext.request.contextPath}/boardtwo/css/deleteFormstyle.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<br><br>
비밀번호가 다릅니다.
<br><br><br>
<a href="javascript:history.go(-1)">[이전으로 돌아가기]</a>
</c:if>
</body>
</html>
cs


구현한 프로젝트의 파일은 다음과 같다.



게시판의 모든 기능이 잘 동작하는지 확인


전체 흐름을 보고 MVC 패턴을 분석한다.


list.do


writeForm.do


updateForm.do


deleteForm.do

반응형

+ Recent posts