Servlet, JSP, JavaBeans, JDBC를 활용하여 게시판을 구현해 보겠습니다.
Model2에 대해 모르시는 분들을 위해 아래에 지난 포스팅 글 첨부하겠습니다.
[JSP] MVC 패턴이란? Model1과 Model2 비교
1. MVC 패턴이란? MVC(Model-View-Controller) 패턴은 사용자 인터페이스, 데이터 및 논리 제어를 구현하는 데 사용되는 디자인 패턴입니다. 기존에 하나의 Servlet이나 JSP로 처리하던 것을 Controller와 View로
recordevelop.tistory.com
1. View
사용자에게 처음 보이는 화면입니다.
글쓰기를 누르면 아래 화면으로 이동합니다.
글쓴이, 비밀번호, 제목, 내용을 입력할 수 있고
파일 선택을 누르면 파일 첨부도 가능합니다.
▶ View는 두 개의 JSP 파일이 있습니다.
1. qna_board_list.jsp
2. qna_board_write.jsp
● qna_board_list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ page import="java.util.*"%>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="net.board.db.*" %>
<%
List boardList=(List)request.getAttribute("boardlist");
int listcount=((Integer)request.getAttribute("listcount")).intValue();
int nowpage=((Integer)request.getAttribute("page")).intValue();
int maxpage=((Integer)request.getAttribute("maxpage")).intValue();
int startpage=((Integer)request.getAttribute("startpage")).intValue();
int endpage=((Integer)request.getAttribute("endpage")).intValue();
%>
<html>
<head>
<title>MVC 게시판</title>
</head>
<body>
<!-- 게시판 리스트 -->
<table width=50% border="0" cellpadding="0" cellspacing="0">
<tr align="center" valign="middle">
<td colspan="4">MVC 게시판</td>
<td align=right>
<font size=2>글 개수 : ${listcount }</font>
</td>
</tr>
<tr align="center" valign="middle" bordercolor="#333333">
<td style="font-family:Tahoma;font-size:8pt;" width="8%" height="26">
<div align="center">번호</div>
</td>
<td style="font-family:Tahoma;font-size:8pt;" width="50%">
<div align="center">제목</div>
</td>
<td style="font-family:Tahoma;font-size:8pt;" width="14%">
<div align="center">작성자</div>
</td>
<td style="font-family:Tahoma;font-size:8pt;" width="17%">
<div align="center">날짜</div>
</td>
<td style="font-family:Tahoma;font-size:8pt;" width="11%">
<div align="center">조회수</div>
</td>
</tr>
<%
for(int i=0;i<boardList.size();i++){
BoardBean bl=(BoardBean)boardList.get(i);
%>
<tr align="center" valign="middle" bordercolor="#333333"
onmouseover="this.style.backgroundColor='F8F8F8'"
onmouseout="this.style.backgroundColor=''">
<td height="23" style="font-family:Tahoma;font-size:10pt;">
<%=bl.getBOARD_NUM()%>
</td>
<td style="font-family:Tahoma;font-size:10pt;">
<div align="left">
<%if(bl.getBOARD_RE_LEV()!=0){ %>
<%for(int a=0;a<=bl.getBOARD_RE_LEV()*2;a++){ %>
<%} %>
▶
<%}else{ %>
▶
<%} %>
<a href="./BoardDetailAction.bo?num=<%=bl.getBOARD_NUM()%>">
<%=bl.getBOARD_SUBJECT()%>
</a>
</div>
</td>
<td style="font-family:Tahoma;font-size:10pt;">
<div align="center"><%=bl.getBOARD_NAME() %></div>
</td>
<td style="font-family:Tahoma;font-size:10pt;">
<div align="center"><%=bl.getBOARD_DATE() %></div>
</td>
<td style="font-family:Tahoma;font-size:10pt;">
<div align="center"><%=bl.getBOARD_READCOUNT() %></div>
</td>
</tr>
<%} %>
<tr align=center height=20>
<td colspan=7 style=font-family:Tahoma;font-size:10pt;>
<%if(nowpage<=1){ %>
[이전]
<%}else{ %>
<a href="./BoardList.bo?page=<%=nowpage-1 %>">[이전]</a>
<%} %>
<%for(int a=startpage;a<=endpage;a++){
if(a==nowpage){%>
[<%=a %>]
<%}else{ %>
<a href="./BoardList.bo?page=<%=a %>">[<%=a %>]</a>
<%} %>
<%} %>
<%if(nowpage>=maxpage){ %>
[다음]
<%}else{ %>
<a href="./BoardList.bo?page=<%=nowpage+1 %>">[다음]</a>
<%} %>
</td>
</tr>
<tr align="right">
<td colspan="5">
<a href="./BoardWrite.bo">[글쓰기]</a>
</td>
</tr>
</table>
</body>
</html>
● qna_board_write.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<html>
<head>
<title>MVC 게시판</title>
<script language="javascript">
function addboard(){
boardform.submit();
}
</script>
</head>
<body>
<!-- 게시판 등록 -->
<form action="./BoardAddAction.bo" method="post"
enctype="multipart/form-data" name="boardform">
<table cellpadding="0" cellspacing="0">
<tr align="center" valign="middle">
<td colspan="5">MVC 게시판</td>
</tr>
<tr>
<td style="font-family:돋음; font-size:12" height="16">
<div align="center">글쓴이</div>
</td>
<td>
<input name="BOARD_NAME" type="text" size="10" maxlength="10"
value=""/>
</td>
</tr>
<tr>
<td style="font-family:돋음; font-size:12" height="16">
<div align="center">비밀번호</div>
</td>
<td>
<input name="BOARD_PASS" type="password" size="10" maxlength="10"
value=""/>
</td>
</tr>
<tr>
<td style="font-family:돋음; font-size:12" height="16">
<div align="center">제 목</div>
</td>
<td>
<input name="BOARD_SUBJECT" type="text" size="50" maxlength="100"
value=""/>
</td>
</tr>
<tr>
<td style="font-family:돋음; font-size:12">
<div align="center">내 용</div>
</td>
<td>
<textarea name="BOARD_CONTENT" cols="67" rows="15"></textarea>
</td>
</tr>
<tr>
<td style="font-family:돋음; font-size:12">
<div align="center">파일 첨부</div>
</td>
<td>
<input name="BOARD_FILE" type="file"/>
</td>
</tr>
<tr bgcolor="cccccc">
<td colspan="2" style="height:1px;">
</td>
</tr>
<tr><td colspan="2"> </td></tr>
<tr align="center" valign="middle">
<td colspan="5">
<a href="javascript:addboard()">[등록]</a>
<a href="javascript:history.go(-1)">[뒤로]</a>
</td>
</tr>
</table>
</form>
<!-- 게시판 등록 -->
</body>
</html>
2. Model
데이터베이스를 사용하기 때문에 테이블부터 생성합니다.
● BOARD
CREATE TABLE BOARD(
BOARD_NUM INT,
BOARD_NAME VARCHAR2(20),
BOARD_PASS VARCHAR2(15),
BOARD_SUBJECT VARCHAR2(50),
BOARD_CONTENT VARCHAR2(2000),
BOARD_FILE VARCHAR2(50),
BOARD_RE_REF INT,
BOARD_RE_LEV INT,
BOARD_RE_SEQ INT,
BOARD_READCOUNT INT,
BOARD_DATE DATE,
PRIMARY KEY(BOARD_NUM)
);
테이블을 생성하면
저는 HR 계정을 사용하므로 HR 계정에 BOARD 테이블이 잘 생성된 것을 확인할 수 있습니다.
▶ 파일 위치
net.board.db 패키지를 만든 후, 2개의 Java 파일을 생성합니다.
→ BoardBean.java : 테이블의 컬럼을 필드로 가지고 있는 클래스
→ BoardDAO.java : Connection Pool을 이용해서 DB에 접속하고 메서드를 통해 쿼리문을 실행
● BoardBean.java
package net.board.db;
import java.sql.Date;
public class BoardBean {
private int BOARD_NUM;
private String BOARD_NAME;
private String BOARD_PASS;
private String BOARD_SUBJECT;
private String BOARD_CONTENT;
private String BOARD_FILE;
private int BOARD_RE_REF;
private int BOARD_RE_LEV;
private int BOARD_RE_SEQ;
private int BOARD_READCOUNT;
private Date BOARD_DATE;
public int getBOARD_NUM() {
return BOARD_NUM;
}
public void setBOARD_NUM(int board_num) {
BOARD_NUM = board_num;
}
public String getBOARD_NAME() {
return BOARD_NAME;
}
public void setBOARD_NAME(String board_name) {
BOARD_NAME = board_name;
}
public String getBOARD_PASS() {
return BOARD_PASS;
}
public void setBOARD_PASS(String board_pass) {
BOARD_PASS = board_pass;
}
public String getBOARD_SUBJECT() {
return BOARD_SUBJECT;
}
public void setBOARD_SUBJECT(String board_subject) {
BOARD_SUBJECT = board_subject;
}
public String getBOARD_CONTENT() {
return BOARD_CONTENT;
}
public void setBOARD_CONTENT(String board_content) {
BOARD_CONTENT = board_content;
}
public String getBOARD_FILE() {
return BOARD_FILE;
}
public void setBOARD_FILE(String board_file) {
BOARD_FILE = board_file;
}
public int getBOARD_RE_REF() {
return BOARD_RE_REF;
}
public void setBOARD_RE_REF(int board_re_ref) {
BOARD_RE_REF = board_re_ref;
}
public int getBOARD_RE_LEV() {
return BOARD_RE_LEV;
}
public void setBOARD_RE_LEV(int board_re_lev) {
BOARD_RE_LEV = board_re_lev;
}
public int getBOARD_RE_SEQ() {
return BOARD_RE_SEQ;
}
public void setBOARD_RE_SEQ(int board_re_seq) {
BOARD_RE_SEQ = board_re_seq;
}
public int getBOARD_READCOUNT() {
return BOARD_READCOUNT;
}
public void setBOARD_READCOUNT(int board_readcount) {
BOARD_READCOUNT = board_readcount;
}
public Date getBOARD_DATE() {
return BOARD_DATE;
}
public void setBOARD_DATE(Date board_date) {
BOARD_DATE = board_date;
}
}
● BoardDAO.java
package net.board.db;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
public class BoardDAO {
Connection con;
PreparedStatement pstmt;
ResultSet rs;
public BoardDAO() {
try{
Context init = new InitialContext();
DataSource ds = (DataSource) init.lookup("java:comp/env/jdbc/OracleDB");
con = ds.getConnection();
}catch(Exception ex){
System.out.println("DB 연결 실패 : " + ex);
return;
}
}
//글의 개수 구하기.
public int getListCount() {
int x= 0;
try{
pstmt=con.prepareStatement("select count(*) from board");
rs = pstmt.executeQuery();
if(rs.next()){
x=rs.getInt(1);
}
}catch(Exception ex){
System.out.println("getListCount 에러: " + ex);
}finally{
if(rs!=null) try{rs.close();}catch(SQLException ex){}
if(pstmt!=null) try{pstmt.close();}catch(SQLException ex){}
}
return x;
}
//글 목록 보기.
public List getBoardList(int page,int limit){
String board_list_sql="select * from "+
"(select rownum rnum,BOARD_NUM,BOARD_NAME,BOARD_SUBJECT,"+
"BOARD_CONTENT,BOARD_FILE,BOARD_RE_REF,BOARD_RE_LEV,"+
"BOARD_RE_SEQ,BOARD_READCOUNT,BOARD_DATE from "+
"(select * from board order by BOARD_RE_REF desc,BOARD_RE_SEQ asc)) "+
"where rnum>=? and rnum<=?";
List list = new ArrayList();
int startrow=(page-1)*10+1; //읽기 시작할 row 번호.
int endrow=startrow+limit-1; //읽을 마지막 row 번호.
try{
pstmt = con.prepareStatement(board_list_sql);
pstmt.setInt(1, startrow);
pstmt.setInt(2, endrow);
rs = pstmt.executeQuery();
while(rs.next()){
BoardBean board = new BoardBean();
board.setBOARD_NUM(rs.getInt("BOARD_NUM"));
board.setBOARD_NAME(rs.getString("BOARD_NAME"));
board.setBOARD_SUBJECT(rs.getString("BOARD_SUBJECT"));
board.setBOARD_CONTENT(rs.getString("BOARD_CONTENT"));
board.setBOARD_FILE(rs.getString("BOARD_FILE"));
board.setBOARD_RE_REF(rs.getInt("BOARD_RE_REF"));
board.setBOARD_RE_LEV(rs.getInt("BOARD_RE_LEV"));
board.setBOARD_RE_SEQ(rs.getInt("BOARD_RE_SEQ"));
board.setBOARD_READCOUNT(rs.getInt("BOARD_READCOUNT"));
board.setBOARD_DATE(rs.getDate("BOARD_DATE"));
list.add(board);
}
return list;
}catch(Exception ex){
System.out.println("getBoardList 에러 : " + ex);
}finally{
if(rs!=null) try{rs.close();}catch(SQLException ex){}
if(pstmt!=null) try{pstmt.close();}catch(SQLException ex){}
}
return null;
}
//글 내용 보기.
public BoardBean getDetail(int num) throws Exception{
BoardBean board = null;
try{
pstmt = con.prepareStatement(
"select * from board where BOARD_NUM = ?");
pstmt.setInt(1, num);
rs= pstmt.executeQuery();
if(rs.next()){
board = new BoardBean();
board.setBOARD_NUM(rs.getInt("BOARD_NUM"));
board.setBOARD_NAME(rs.getString("BOARD_NAME"));
board.setBOARD_SUBJECT(rs.getString("BOARD_SUBJECT"));
board.setBOARD_CONTENT(rs.getString("BOARD_CONTENT"));
board.setBOARD_FILE(rs.getString("BOARD_FILE"));
board.setBOARD_RE_REF(rs.getInt("BOARD_RE_REF"));
board.setBOARD_RE_LEV(rs.getInt("BOARD_RE_LEV"));
board.setBOARD_RE_SEQ(rs.getInt("BOARD_RE_SEQ"));
board.setBOARD_READCOUNT(rs.getInt("BOARD_READCOUNT"));
board.setBOARD_DATE(rs.getDate("BOARD_DATE"));
}
return board;
}catch(Exception ex){
System.out.println("getDetail 에러 : " + ex);
}finally{
if(rs!=null)try{rs.close();}catch(SQLException ex){}
if(pstmt !=null)try{pstmt.close();}catch(SQLException ex){}
}
return null;
}
//글 등록.
public boolean boardInsert(BoardBean board){
int num =0;
String sql="";
int result=0;
try{
pstmt=con.prepareStatement("select max(board_num) from board");
rs = pstmt.executeQuery();
if(rs.next())
num =rs.getInt(1)+1;
else
num=1;
sql="insert into board (BOARD_NUM,BOARD_NAME,BOARD_PASS,BOARD_SUBJECT,";
sql+="BOARD_CONTENT, BOARD_FILE, BOARD_RE_REF,"+
"BOARD_RE_LEV,BOARD_RE_SEQ,BOARD_READCOUNT,"+
"BOARD_DATE) values(?,?,?,?,?,?,?,?,?,?,sysdate)";
pstmt = con.prepareStatement(sql);
pstmt.setInt(1, num);
pstmt.setString(2, board.getBOARD_NAME());
pstmt.setString(3, board.getBOARD_PASS());
pstmt.setString(4, board.getBOARD_SUBJECT());
pstmt.setString(5, board.getBOARD_CONTENT());
pstmt.setString(6, board.getBOARD_FILE());
pstmt.setInt(7, num);
pstmt.setInt(8, 0);
pstmt.setInt(9, 0);
pstmt.setInt(10, 0);
result=pstmt.executeUpdate();
if(result==0)return false;
return true;
}catch(Exception ex){
System.out.println("boardInsert 에러 : "+ex);
}finally{
if(rs!=null) try{rs.close();}catch(SQLException ex){}
if(pstmt!=null) try{pstmt.close();}catch(SQLException ex){}
}
return false;
}
//글 답변.
public int boardReply(BoardBean board){
String board_max_sql="select max(board_num) from board";
String sql="";
int num=0;
int result=0;
int re_ref=board.getBOARD_RE_REF();
int re_lev=board.getBOARD_RE_LEV();
int re_seq=board.getBOARD_RE_SEQ();
try{
pstmt=con.prepareStatement(board_max_sql);
rs = pstmt.executeQuery();
if(rs.next())num =rs.getInt(1)+1;
else num=1;
sql="update board set BOARD_RE_SEQ=BOARD_RE_SEQ+1 where BOARD_RE_REF=? ";
sql+="and BOARD_RE_SEQ>?";
pstmt = con.prepareStatement(sql);
pstmt.setInt(1,re_ref);
pstmt.setInt(2,re_seq);
result=pstmt.executeUpdate();
re_seq = re_seq + 1;
re_lev = re_lev+1;
sql="insert into board (BOARD_NUM,BOARD_NAME,BOARD_PASS,BOARD_SUBJECT,";
sql+="BOARD_CONTENT, BOARD_FILE,BOARD_RE_REF,BOARD_RE_LEV,BOARD_RE_SEQ,";
sql+="BOARD_READCOUNT,BOARD_DATE) values(?,?,?,?,?,?,?,?,?,?,sysdate)";
pstmt = con.prepareStatement(sql);
pstmt.setInt(1, num);
pstmt.setString(2, board.getBOARD_NAME());
pstmt.setString(3, board.getBOARD_PASS());
pstmt.setString(4, board.getBOARD_SUBJECT());
pstmt.setString(5, board.getBOARD_CONTENT());
pstmt.setString(6, ""); //답장에는 파일을 업로드하지 않음.
pstmt.setInt(7, re_ref);
pstmt.setInt(8, re_lev);
pstmt.setInt(9, re_seq);
pstmt.setInt(10, 0);
pstmt.executeUpdate();
return num;
}catch(SQLException ex){
System.out.println("boardReply 에러 : "+ex);
}finally{
if(rs!=null)try{rs.close();}catch(SQLException ex){}
if(pstmt!=null)try{pstmt.close();}catch(SQLException ex){}
}
return 0;
}
//글 수정.
public boolean boardModify(BoardBean modifyboard) throws Exception{
String sql="update board set BOARD_SUBJECT=?,BOARD_CONTENT=? where BOARD_NUM=?";
try{
pstmt = con.prepareStatement(sql);
pstmt.setString(1, modifyboard.getBOARD_SUBJECT());
pstmt.setString(2, modifyboard.getBOARD_CONTENT());
pstmt.setInt(3, modifyboard.getBOARD_NUM());
pstmt.executeUpdate();
return true;
}catch(Exception ex){
System.out.println("boardModify 에러 : " + ex);
}finally{
if(rs!=null)try{rs.close();}catch(SQLException ex){}
if(pstmt!=null)try{pstmt.close();}catch(SQLException ex){}
}
return false;
}
//글 삭제.
public boolean boardDelete(int num){
String board_delete_sql="delete from board where BOARD_num=?";
int result=0;
try{
pstmt=con.prepareStatement(board_delete_sql);
pstmt.setInt(1, num);
result=pstmt.executeUpdate();
if(result==0)return false;
return true;
}catch(Exception ex){
System.out.println("boardDelete 에러 : "+ex);
}finally{
try{
if(pstmt!=null)pstmt.close();
}catch(Exception ex) {}
}
return false;
}
//조회수 업데이트.
public void setReadCountUpdate(int num) throws Exception{
String sql="update board set BOARD_READCOUNT = "+
"BOARD_READCOUNT+1 where BOARD_NUM = "+num;
try{
pstmt=con.prepareStatement(sql);
pstmt.executeUpdate();
}catch(SQLException ex){
System.out.println("setReadCountUpdate 에러 : "+ex);
}
}
//글쓴이인지 확인.
public boolean isBoardWriter(int num,String pass){
String board_sql="select * from board where BOARD_NUM=?";
try{
pstmt=con.prepareStatement(board_sql);
pstmt.setInt(1, num);
rs=pstmt.executeQuery();
rs.next();
if(pass.equals(rs.getString("BOARD_PASS"))){
return true;
}
}catch(SQLException ex){
System.out.println("isBoardWriter 에러 : "+ex);
}
return false;
}
}
3. Controller
Request를 받으면 Model과 View를 연결하는 통로 역할을 합니다.
▶ 파일 위치
net.board.db 패키지를 만든 후, 4개의 Java 파일을 생성합니다.
- Action.java는 인터페이스로 생성해 줍니다.
-BoardFrontController는 Controller의 가장 핵심이 되는 파일입니다. Servlet으로 생성해야 합니다.
※ Servlet Mapping
<servlet>
<servlet-name>BoardFrontController</servlet-name>
<servlet-class>net.board.action.BoardFrontController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>BoardFrontController</servlet-name>
<url-pattern>*.bo</url-pattern>
</servlet-mapping>
web.xml 파일에 servlet-mapping 코드를 위와 같이 적어줍니다.
● Action.java
package net.board.action;
import javax.servlet.http.*;
public interface Action {
public ActionForward execute(HttpServletRequest request, HttpServletResponse response) throws Exception;
}
● ActionFoward.java
package net.board.action;
public class ActionForward {
private boolean isRedirect=false;
private String path=null;
public boolean isRedirect() {
return isRedirect;
}
public void setRedirect(boolean isRedirect) {
this.isRedirect = isRedirect;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}
● BoardFrontController.java
package net.board.action;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/BoardFrontController")
public class BoardFrontController extends HttpServlet {
private static final long serialVersionUID = 1L;
public BoardFrontController() {
super();
}
protected void doProcess(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String RequestURI = request.getRequestURI();
String contextPath = request.getContextPath();
String command = RequestURI.substring(contextPath.length());
ActionForward forward = null; //전송 방식과 전송할 URL을 가지고 있는 클래스
Action action = null; //동적 바인딩을 하기 위한 코드
if(command.equals("/BoardList.bo")){ // 게시판 리스트는 DB를 가지고온다.
action = new BoardListAction();
try{
forward = action.execute(request, response);
} catch(Exception e){
e.printStackTrace();
}
} else if(command.equals("/BoardWrite.bo")){
forward= new ActionForward();
forward.setRedirect(false);
forward.setPath("./board/qna_board_write.jsp");
}
if(forward.isRedirect()) {
response.sendRedirect(forward.getPath());
} else {
RequestDispatcher dispatcher=
request.getRequestDispatcher(forward.getPath());
dispatcher.forward(request, response);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doProcess(request,response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doProcess(request,response);
}
}
● BoardListAction.java
package net.board.action;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.board.db.BoardDAO;
public class BoardListAction implements Action {
public ActionForward execute(HttpServletRequest request,HttpServletResponse response) throws Exception{
BoardDAO boarddao=new BoardDAO();
List boardlist=new ArrayList();
int page=1;
int limit=10;
if(request.getParameter("page")!=null){
page=Integer.parseInt(request.getParameter("page"));
}
int listcount=boarddao.getListCount(); //총 리스트 수를 받아옴.
boardlist = boarddao.getBoardList(page,limit); //리스트를 받아옴.
//총 페이지 수.
int maxpage=(int)((double)listcount/limit+0.95); //0.95를 더해서 올림 처리.
//현재 페이지에 보여줄 시작 페이지 수(1, 11, 21 등...)
int startpage = (((int) ((double)page / 10 + 0.9)) - 1) * 10 + 1;
//현재 페이지에 보여줄 마지막 페이지 수.(10, 20, 30 등...)
int endpage = maxpage;
if (endpage>startpage+10-1) endpage=startpage+10-1;
request.setAttribute("page", page); //현재 페이지 수.
request.setAttribute("maxpage", maxpage); //최대 페이지 수.
request.setAttribute("startpage", startpage); //현재 페이지에 표시할 첫 페이지 수.
request.setAttribute("endpage", endpage); //현재 페이지에 표시할 끝 페이지 수.
request.setAttribute("listcount",listcount); //글 수.
request.setAttribute("boardlist", boardlist);
ActionForward forward= new ActionForward();
forward.setRedirect(false);
forward.setPath("./board/qna_board_list.jsp");
return forward;
}
}
다음 시간에는 게시판의 기능을 구현해 보겠습니다.