2024-12-23



====================================== web.xml ======================================
<display-name>10_Board</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 서블릿 매핑(N:1) -->
<servlet>
<servlet-name>FrontController</servlet-name>
<servlet-class>com.board.controller.FrontController</servlet-class>
</servlet>
<servlet-mapping> <!-- 위 Servlet 태그와 이름이 같아야 mapping이 가능함 -->
<servlet-name>FrontController</servlet-name>
<url-pattern>*.go</url-pattern>
</servlet-mapping>
</web-app>
====================================== FrontController.jave ======================================
package com.board.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.board.action.*;
public class FrontController extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 한글 깨짐 방지 작업 설정
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
// getRequestURI() : "/프로젝트명/파일명(*.go)" 를 문자열로 반환해 주는 메서드
String uri = request.getRequestURI();
System.out.println("URI >>> " + uri); // URI >>> /10_Board/list.go
// getContextPath() : 현재 프로젝트명을 문자열로 반환해 주는 메서드
String path = request.getContextPath();
System.out.println("PATH >>> " + path); // PATH >>> /10_Board
String command = uri.substring(path.length() + 1);
System.out.println("command >>> " + command); // command >>> list.go
Action action = null;
if (command.equals("list.go")) {
action = new BoardListAction();
} else if (command.equals("write_ok.go")) {
action = new BoardWriteOkAction();
} else if (command.equals("content.go")) {
action = new BoardContentAction();
} else if (command.equals("modify.go")) {
action = new BoardModifyAction();
} else if (command.equals("modify_ok.go")) {
action = new BoardModifyOkAction();
} else if (command.equals("delete_ok.go")) {
action = new BoardDeleteOkAction();
} else if (command.equals("search.go")) {
action = new BoardSearchListAction();
}
String viewPage = action.execute(request, response);
request.getRequestDispatcher(viewPage).forward(request, response);
}
}
====================================== Action.jave ======================================
package com.board.action;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface Action {
String execute(HttpServletRequest request, HttpServletResponse response) throws IOException;
}
====================================== BoardDAO.jave ======================================
package com.board.model;
import java.sql.Connection;
import java.sql.DriverManager;
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 {
// DB와 연결하는 객체
Connection con = null;
// DB에 SQL문을 전송하는 객체
PreparedStatement pstmt = null;
//SQL문을 실행한 후에 결과값을 가지고 있는 객체
ResultSet rs = null;
// SQL문을 저장할 변수
String sql = null;
// BoardDAO 클래스를 싱글턴 방식으로 만들어 보자.
// 1단계 : BoardDAO 클래스를 정적(static)멤버로 선언을 해 주어야 한다.
private static BoardDAO instance = null;
// 2단계 : 싱글턴 방식으로 객체를 만들기 위해서는 기본 생성자의 접근지정자를 public
// 에서 private 으로 변경해 주어야 함. 즉, 외부에서 직접적으로 기본 생성자에
// 접근하여 객체를 생성하거나 호출하지 못 하도록 해야 함.
private BoardDAO() {} // 기본 생성자
// 3단계 : 기본 생성자 대신에 싱글턴 객체를 return 해주는 getInstance() 라는
// 메서드를 만들어서 해당 getInstance() 메서드를 외부에서 접근이 가능하도록
// 해 주면 됨.
public static BoardDAO getInstance() {
if (instance == null) {
instance = new BoardDAO();
}
return instance;
} // getInstance() 메서드 end
// DB연동 작업을 하는 메서드(DBCP 방식)
public void openConn() {
try {
// 1단계 : JNDI 서버 객체 생성
// 자바의 네이밍 서비스(JNDI)에서 이름과 실제 객체를 연결해 주는 개념이 Context 객체이며,
// InitialContext 객체는 네이밍 서비스를 이용하기 위한 시작점이 됨.
Context init = new InitialContext();
// 2단계 : COntext 라는 객체를 얻어와야 함.
// "java:comp/env" 라는 이름의 인수로 Context 객체를 얻어옴. "java:comp/env" 는
// 현재 웹 애플리케이션에서 네이밍 서비스를 이용시 루트 디렉토리라고 생각하면 됨. 즉, 현재
// 웹 애플리케이션이 사용할 수 있는 모든 자원은 "java:comp/env" 아래에 위치하게 됨.
Context ctx = (Context)init.lookup("java:comp/env");
// 3단계 : lookup() 메서드를 이용하여 매칭되는 커넥션을 찾게 됨.
// "java:comp/env" 아래에 위치한 "jdbc/myoracle" 이라는 자원을 얻어오게 됨. 이 자원이 바로
// 데이터소스(커넥션 풀)임. 여기서 "jdbc/myoracle" 은 context.xml 파일에 추가했던 <Resource>
// 태그 안에 있던 name 속성의 값임.
DataSource ds = (DataSource)ctx.lookup("jdbc/myoracle");
// 4단계 : DataSource 객체를 이용하여 커넥션을 하나 가져오면 됨.
con = ds.getConnection();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} // openConn() 메서드 end
// DB에 연결되어 있던 자원 종료하기
public void closeConn(ResultSet rs, PreparedStatement pstmt, Connection con) {
try {
if (rs != null) rs.close();
if (pstmt != null) pstmt.close();
if (con != null) con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} // closeConn() 메서드 end
// DB에 연결되어 있던 자원 종료하기
public void closeConn(PreparedStatement pstmt, Connection con) {
try {
if (pstmt != null) pstmt.close();
if (con != null) con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} // closeConn() 메서드 end
// board 테이블의 전체 게시물의 수를 확인하는 메서드
public int getBoardCount() {
int count = 0;
try {
openConn();
sql = "select count(*) from board"; // 레코드의 수 반환
pstmt = con.prepareStatement(sql);
rs = pstmt.executeQuery();
if (rs.next()) {
count = rs.getInt(1);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
closeConn(rs, pstmt, con);
}
return count;
} // getBoardCount() 메서드 end
// board 테이블에서 현재 페이지에 해당하는 게시물을 조회하는 메서드
public List<BoardDTO> getBoardList(int page, int rowsize) {
List<BoardDTO> list = new ArrayList<BoardDTO>();
// 해당 페이지에서 시작 글 번호
int startNo = (page * rowsize) - (rowsize - 1);
// 해당 페이지에서 끝 글 번호
int endNo = (page * rowsize);
try {
openConn();
sql = "SELECT * FROM "
+ " (SELECT ROW_NUMBER() OVER(ORDER BY board_no DESC) AS rnum, b.* FROM board b) "
+ " WHERE rnum >= ? AND rnum <= ?";
pstmt = con.prepareStatement(sql);
pstmt.setInt(1, startNo);
pstmt.setInt(2, endNo);
rs = pstmt.executeQuery();
while (rs.next()) {
BoardDTO dto = new BoardDTO();
dto.setBoard_no(rs.getInt("board_no"));
dto.setBoard_writer(rs.getString("board_writer"));
dto.setBoard_title(rs.getString("board_title"));
dto.setBoard_cont(rs.getString("board_cont"));
dto.setBoard_pwd(rs.getString("board_pwd"));
dto.setBoard_hit(rs.getInt("board_hit"));
dto.setBoard_date(rs.getString("board_date"));
dto.setBoard_update(rs.getString("board_update"));
list.add(dto);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
closeConn(rs, pstmt, con);
}
return list;
} // getBoardList() 메서드 end
}
====================================== BoardDTO.jave ======================================
package com.board.model;
public class BoardDTO {
private int board_no;
private String board_writer;
private String board_title;
private String board_cont;
private String board_pwd;
private int board_hit;
private String board_date;
private String board_update;
public int getBoard_no() {
return board_no;
}
public void setBoard_no(int board_no) {
this.board_no = board_no;
}
public String getBoard_writer() {
return board_writer;
}
public void setBoard_writer(String board_writer) {
this.board_writer = board_writer;
}
public String getBoard_title() {
return board_title;
}
public void setBoard_title(String board_title) {
this.board_title = board_title;
}
public String getBoard_cont() {
return board_cont;
}
public void setBoard_cont(String board_cont) {
this.board_cont = board_cont;
}
public String getBoard_pwd() {
return board_pwd;
}
public void setBoard_pwd(String board_pwd) {
this.board_pwd = board_pwd;
}
public int getBoard_hit() {
return board_hit;
}
public void setBoard_hit(int board_hit) {
this.board_hit = board_hit;
}
public String getBoard_date() {
return board_date;
}
public void setBoard_date(String board_date) {
this.board_date = board_date;
}
public String getBoard_update() {
return board_update;
}
public void setBoard_update(String board_update) {
this.board_update = board_update;
}
}
====================================== BoardListAction.jave ======================================
package com.board.action;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.board.model.BoardDAO;
import com.board.model.BoardDTO;
public class BoardListAction implements Action {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) {
// 요청 : 게시물 전체 목록을 보여달라고 요청.
// 응답 : board 테이블의 전체 게시물 목록을 조회하여 view page 로 이동시키는 비지니스 로직
// 이 때 비지니스 로직 작업 시에 페이징 처리 작업도 병행.
// 페이징 작업 진행
// 한 페이지당 보여지는 게시물의 수
int rowsize = 3;
// 아래에 보여지는 페이지의 최대 블럭 수 ==> [1][2][3] / [4][5][6]
int block = 3;
// board 테이블 상의 게시물의 전체 수
int totalRecord = 0;
// 전체 페이지 수
int allPage = 0;
// 현재 페이지 변수
int page = 0;
if (request.getParameter("page") != null) {
page = Integer.parseInt(request.getParameter("page"));
} else {
// 처음으로 main 페이지에서 "게시물 전체 목록" a 태그를 클릭한 경우
page = 1; // 1 페이지로 넘어감
}
// 해당 페이지에서 시작 글 번호
int startNo = (page * rowsize) - (rowsize - 1);
// 해당 페이지에서 끝 글 번호
int endNo = (page * rowsize);
// 해당 페이지에서 시작 블럭
int startBlock = (((page - 1) / block) * block) + 1;
// 해당 페이지에서 끝 블럭
int endBlock = (((page - 1) / block) * block) + block;
BoardDAO dao = BoardDAO.getInstance();
// 전체 게시물의 수를 확인하는 메서드 호출
totalRecord = dao.getBoardCount();
// 전체 게시물 수를 한 페이지당 보여질 게시물의 수로 나누어주면 전체 페이지 수가 나옴.
allPage = (int)Math.ceil(totalRecord / (double)rowsize);
// 데이터가 없는 글 번호가 생기지 않게 하는 로직
if (endBlock > allPage) {
endBlock = allPage;
}
// 현재 페이지에 해당하는 게시물을 가져오는 메서드 호출
List<BoardDTO> boardList = dao.getBoardList(page, rowsize);
// 페이징 작업 후에는 지금까지 페이징 처리 시에 작업했던 모든 정보들을 view page 로 바인딩시켜 주어야 한다.
request.setAttribute("page", page);
request.setAttribute("rowsize", rowsize);
request.setAttribute("block", block);
request.setAttribute("totalRecord", totalRecord);
request.setAttribute("allPage", allPage);
request.setAttribute("startNo", startNo);
request.setAttribute("endNo", endNo);
request.setAttribute("startBlock", startBlock);
request.setAttribute("endBlock", endBlock);
request.setAttribute("List", boardList);
return "views/board_list.jsp";
}
}
====================================== main.jave ======================================
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div align="center">
<hr width="30%" color="blue">
<h3>BOARD 메인 페이지</h3>
<hr width="30%" color="blue">
<br> <br>
<a href="<%= request.getContextPath() %>/list.go">[전체 게시물 목록]</a>
</div>
</body>
</html>'JSP > 기초 내용 정리' 카테고리의 다른 글
| JSP(Ajax)_00 (1) | 2024.12.31 |
|---|---|
| JSP(Example)_FileUpload (1) | 2024.12.27 |
| Java(Example)_MEMBER2 (0) | 2024.12.23 |
| JSP(JSTL)_04 (1) | 2024.12.19 |
| JSP(JSTL)_03 (1) | 2024.12.19 |