Study Web Development

1월 17일

이전으로

Servlet & JSP

6. 모델 1 방식으로 DB 연동하기

m1_member

UI
  1. views 폴더에 새 JSP 파일 myPage.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="kr.member.dao.MemberDAO" %>
<%@ page import="kr.member.vo.MemberVO" %>
<%
	Integer user_num = (Integer)session.getAttribute("user_num"); // getAttribute() 메서드는 Object를 반환하므로 Integer로 형변환
	if(user_num==null) { // 로그인되지 않은 경우
		response.sendRedirect("loginForm.jsp");
	}
	else { // 로그인되어 있는 경우
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 상세 정보</title>
<link rel="stylesheet" href="<%= request.getContextPath() %>/css/layout.css">
</head>
<body>
<%
	MemberDAO dao = MemberDAO.getInstance();
	MemberVO member = dao.getMember(user_num);
	if(member.getPhone()==null) {
		member.setPhone(""); // null 대신 빈 문자열 출력
	}
%>
<div class="page-main">
	<h1>회원 상세 정보</h1>
	<ul>
		<li>아이디 : <%= member.getId() %></li>
		<li>이름 : <%= member.getName() %></li>
		<li>이메일 : <%= member.getEmail() %></li>
		<li>전화번호 : <%= member.getPhone() %></li>
		<li>가입일 : <%= member.getReg_date() %></li>
	</ul>
	<hr width="100%" size="1" noshade>
	<div class="align-right">
		<input type="button" value="회원 정보 수정" onclick="location.href = 'modifyUserForm.jsp';">
		<input type="button" value="회원 탈퇴" onclick="location.href = 'deleteUserForm.jsp';">
		<input type="button" value="홈으로" onclick="location.href = 'main.jsp';">
	</div>
</div>
</body>
</html>
<%
	}
%>
  1. 새 JSP 파일 modifyUserForm.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="kr.member.dao.MemberDAO" %>
<%@ page import="kr.member.vo.MemberVO" %>
<%
	Integer user_num = (Integer)session.getAttribute("user_num");
	if(user_num==null) { // 로그인되지 않은 경우
		response.sendRedirect("loginForm.jsp");
	}
	else { // 로그인되어 있는 경우
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 정보 수정</title>
<link rel="stylesheet" href="<%= request.getContextPath() %>/css/layout.css">
<script type="text/javascript">
	window.onload = function() {
		document.getElementById('modify_form').onsubmit = function() {
			var name = document.getElementById('name');
			if(name.value.trim()=='') {
				alert('이름을 입력하세요!');
				name.value = '';
				name.focus();
				return false;
			}
			var passwd = document.getElementById('passwd');
			if(passwd.value.trim()=='') {
				alert('비밀번호를 입력하세요!');
				passwd.value = '';
				passwd.focus();
				return false;
			}
			var email = document.getElementById('email');
			if(email.value.trim()=='') {
				alert('이메일을 입력하세요!');
				email.value = '';
				email.focus();
				return false;
			}
		};
	};
</script>
</head>
<body>
<%
	MemberDAO dao = MemberDAO.getInstance();
	MemberVO member = dao.getMember(user_num);
	if(member.getPhone()==null) {
		member.setPhone(""); // null 대신 빈 문자열 출력
	}
%>
<div class="page-main">
	<h1>회원 정보 수정</h1>
	<form action="modifyUser.jsp" method="post" id="modify_form">
		<ul>
			<li>
				<label for="name">이름</label>
				<input type="text" name="name" id="name" value="<%= member.getName() %>" maxlength="10">
			</li>
			<li>
				<label for="passwd">비밀번호</label>
				<input type="password" name="passwd" id="passwd" maxlength="12"> <!-- 수정은 가능하지만 미리보기는 허용하지 않음 -->
			</li>
			<li>
				<label for="email">이메일</label>
				<input type="email" name="email" id="email" value="<%= member.getEmail() %>" maxlength="50">
			</li>
			<li>
				<label for="phone">전화번호</label>
				<input type="text" name="phone" id="phone" value="<%= member.getPhone() %>" maxlength="15">
			</li>
		</ul>
		<div class="align-center">
			<input type="submit" value="수정">
			<input type="button" value="홈으로" onclick="location.href = 'main.jsp';">
		</div>
	</form>
</div>
</body>
</html>
<%
	}
%>
  1. 새 JSP 파일 modifyUser.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="kr.member.dao.MemberDAO" %>
<%
	Integer user_num = (Integer)session.getAttribute("user_num");
	if(user_num==null) { // 로그인되어 있지 않은 경우
		response.sendRedirect("loginForm.jsp");
	}
	else { // 로그인되어 있는 경우
		// 전송된 데이터 인코딩 처리
		request.setCharacterEncoding("UTF-8");
%>
<jsp:useBean id="member" class="kr.member.vo.MemberVO"/>
<jsp:setProperty property="*" name="member"/>
<%
		// num이 전송되지 않았기 때문에 session에 저장된 num을 이용
		member.setNum(user_num);
		
		MemberDAO dao = MemberDAO.getInstance();
		dao.updateMember(member);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 정보 수정 완료</title>
<link rel="stylesheet" href="<%= request.getContextPath() %>/css/layout.css">
</head>
<body>

</body>
</html>
<%
	}
%>
  1. 새 JSP 파일 deleteUserForm.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	Integer user_num = (Integer)session.getAttribute("user_num");
	if(user_num==null) { // 로그인되어 있지 않은 경우
		response.sendRedirect("loginForm.jsp");
	}
	else { // 로그인되어 있는 경우
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 탈퇴 폼</title>
<link rel="stylesheet" href="<%= request.getContextPath() %>/css/layout.css">
<script type="text/javascript">
	window.onload = function() {
		document.getElementById('delete_form').onsubmit = function() {
			var id = document.getElementById('id');
			if(id.value.trim()=='') {
				alert('아이디를 입력하세요!');
				id.value = '';
				id.focus();
				return false;
			}
			var passwd = document.getElementById('passwd');
			if(passwd.value.trim()=='') {
				alert('비밀번호를 입력하세요!');
				passwd.value = '';
				passwd.focus();
				return false;
			}
			var cpasswd = document.getElementById('cpasswd');
			if(cpasswd.value.trim()=='') {
				alert('비밀번호 확인을 입력하세요!');
				cpasswd.value = '';
				cpasswd.focus();
				return false;
			}
			
			// 비밀번호와 비밀번호 확인 일치 여부 체크
			if(passwd.value != cpasswd.value) {
				alert('비밀번호와 비밀번호 확인이 불일치합니다!');
				cpasswd.value = '';
				cpasswd.focus();
				return false;
			}
		};
	};
</script>
</head>
<body>
<div class="page-main">
	<h1>회원 탈퇴</h1>
	<form id="delete_form" action="deleteUser.jsp" method="post">
		<ul>
			<li>
				<label for="id">아이디</label>
				<input type="text" name="id" id="id" maxlength="12">
			</li>
			<li>
				<label for="passwd">비밀번호</label>
				<input type="password" name="passwd" id="passwd" maxlength="12">
			</li>
			<li>
				<label for="cpasswd">비밀번호 확인</label>
				<input type="password" name="cpasswd" id="cpasswd" maxlength="12">
			</li>
		</ul>
		<div class="align-center">
			<input type="submit" value="회원 탈퇴">
			<input type="button" value="홈으로" onclick="location.href = 'main.jsp';">
		</div>
	</form>
</div>
</body>
</html>
<%
	}
%>
  1. 새 JSP 파일 deleteUser.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="kr.member.dao.MemberDAO" %>
<%@ page import="kr.member.vo.MemberVO" %>
<%
	String user_id = (String)session.getAttribute("user_id");
	if(user_id==null) { // 로그인되지 않은 경우
		response.sendRedirect("loginForm.jsp");
	}
	else { // 로그인되어 있는 경우
		// 전송된 데이터 인코딩 처리
		request.setCharacterEncoding("UTF-8");
		
		// 전송된 데이터 반환
		String id = request.getParameter("id");
		String passwd = request.getParameter("passwd");
		
		// 아이디와 비밀번호 일치 여부 체크
		MemberDAO dao = MemberDAO.getInstance();
		MemberVO member = dao.checkMember(id);		
		boolean check = false;
		// 로그인할 때 사용한 아이디와 회원 탈퇴시 입력한 아이디 일치 여부 체크
		if(member!=null && user_id.equals(id)) {
			// 비밀번호 일치 여부 체크
			check = member.isCheckedPassword(passwd);
		}
		if(check) { // 인증 성공
			// 회원 정보 삭제
			dao.deleteMember(member.getNum());
			// 로그아웃
			session.invalidate();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 탈퇴</title>
<link rel="stylesheet" href="<%= request.getContextPath() %>/css/layout.css">
</head>
<body>
<div class="page-main">
	<h1>회원 탈퇴 완료</h1>
	<div class="result-display">
		<div class="align-center">
			회원 탈퇴가 완료되었습니다.<br>
			<input type="button" value="홈으로" onclick="location.href = 'main.jsp';">
		</div>
	</div>
</div>
</body>
</html>
<%
		}
		else { // 인증 실패
%>
<script type="text/javascript">
	alert('아이디 또는 비밀번호가 불일치합니다!');
	history.go(-1);
</script>
<%
		}
	}
%>

m1_board

프로젝트 생성 및 설정
  1. 새 다이나믹 웹 프로젝트를 생성하여 프로젝트명에 m1_board 입력 후 Next-Next-Generate web.xml depolyment descriptor 선택 후 Finish
  2. 프로젝트를 오른쪽 클릭하여 Build Path-Configure Build Path... 선택하고 Libraries 탭에서 JRE System Library를 선택 후 Edit...에서 JavaSE-1.8(jre)로 변경
  3. 프로젝트를 오른쪽 클릭하여 Properties 선택하고 좌측 목록에서 Project Facets 선택 후 Java의 Version을 1.8로 변경
  4. C:\javaWork\apps에서 ojdbc8.jar를 복사하여 C:\javaWork\workspace_jsp\m1_board\src\main\webapp\WEB-INF\lib에 붙여넣기
  5. m1_member 프로젝트의 webapp/META-INF 폴더에서 context.xml을 복사하여 m1_board 프로젝트의 webapp/META-INF 폴더에 붙여넣기
  6. m1_member 프로젝트의 webapp 폴더에서 css 폴더를 복사하여 m1_board 프로젝트의 webapp 폴더에 붙여넣기 후 layout.css 하단에 다음을 추가
/* 목록 */
table {
	width: 100%;
	border: 1px solid #000;
	border-collapse: collapse;
	margin-top: 5px;
}
table td, table th {
	border: 1px solid #000;
	padding: 5px;
}
  1. m1_board 프로젝트의 webapp 폴더 오른쪽 클릭 후 새 폴더 js 생성하고 jquery-3.6.0.min.js 파일을 해당 폴더로 이동
  2. src/main/webapp 폴더 오른쪽 클릭하고 새 폴더 sql 생성 후 table.sql 생성
CREATE TABLE sboard(
	num NUMBER PRIMARY KEY,
	title VARCHAR2(150) NOT NULL,
	name VARCHAR2(30) NOT NULL,
	passwd VARCHAR2(12) NOT NULL,
	content CLOB NOT NULL,
	ip VARCHAR2(30) NOT NULL,
	reg_date DATE NOT NULL
);

CREATE SEQUENCE sboard_seq;
  1. src/main/java 오른쪽 클릭하여 새 패키지 kr.util 생성하고 PagingUtil.java를 해당 패키지로 이동
자바빈
  1. src/main/java 오른쪽 클릭하여 새 패키지 kr.board.vo 생성하고 새 클래스 BoardVO 생성
package kr.board.vo;

import java.sql.Date;

public class BoardVO {
	private int num; // 글 번호
	private String title; // 제목
	private String name; // 작성자
	private String passwd; // 비밀번호
	private String content; // 내용
	private String ip; // 작성자 IP
	private Date reg_date; // 작성일
	
	// 비밀번호 일치 여부 체크
	public boolean isCheckedPassword(String user_passwd) {
		if(passwd.equals(user_passwd)) {
			return true;
		}
		return false;
	}
	
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPasswd() {
		return passwd;
	}
	public void setPasswd(String passwd) {
		this.passwd = passwd;
	}
	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;
	}
	public Date getReg_date() {
		return reg_date;
	}
	public void setReg_date(Date reg_date) {
		this.reg_date = reg_date;
	}
}
DAO
  1. src/main/java 오른쪽 클릭하여 새 패키지 kr.board.dao 생성하고 새 클래스 BoardDAO 생성
package kr.board.dao;

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;

import kr.board.vo.BoardVO;

public class BoardDAO {
	// 싱글턴 패턴
	private static BoardDAO instance = new BoardDAO();
	
	public static BoardDAO getInstance() {
		return instance;
	}
	
	private BoardDAO() {};
	
	// context.xml에서 설정 정보를 읽어들여 커넥션 풀로부터 커넥션을 할당받음
	private Connection getConnection() throws Exception {
		Context initCtx = new InitialContext();
		DataSource ds = (DataSource)initCtx.lookup("java:comp/env/jdbc/xe");
		return ds.getConnection();
	}
	
	// 자원 정리
	private void executeClose(ResultSet rs, PreparedStatement pstmt, Connection conn) {
		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) {}
	}
	
	// 글 저장
	public void insert(BoardVO boardVO) throws Exception {
		Connection conn = null;
		PreparedStatement pstmt = null;
		String sql = null;
		
		try {
			// 커넥션 풀로부터 커넥션을 할당
			conn = getConnection();
			
			// SQL문 작성
			sql = "INSERT INTO sboard (num, title, name, passwd, content, ip, reg_date) "
				+ "VALUES (sboard_seq.NEXTVAL, ?, ?, ?, ?, ?, SYSDATE)";
			
			// PreparedStatement 객체 생성
			pstmt = conn.prepareStatement(sql);
			// ?에 데이터를 바인딩
			pstmt.setString(1, boardVO.getTitle());
			pstmt.setString(2, boardVO.getName());
			pstmt.setString(3, boardVO.getPasswd());
			pstmt.setString(4, boardVO.getContent());
			pstmt.setString(5, boardVO.getIp());
			
			// SQL문 실행
			pstmt.executeUpdate();
		}
		catch(Exception e) {
			throw new Exception(e);
		}
		finally {
			// 자원 정리
			executeClose(null, pstmt, conn);
		}
	}
	
	// 글의 총 갯수
	public int getCount() throws Exception {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String sql = null;
		int count = 0;
		
		try {
			// 커넥션 풀로부터 커넥션을 할당
			conn = getConnection();
			
			// SQL문 작성
			sql = "SELECT COUNT(*) FROM sboard";
			
			// PreparedStatement 객체 생성
			pstmt = conn.prepareStatement(sql);
			
			// SQL문을 실행해서 결과 행을 ResultSet에 담아 반환
			rs = pstmt.executeQuery();
			if(rs.next()) {
				count = rs.getInt(1);
			}
		}
		catch(Exception e) {
			throw new Exception(e);
		}
		finally {
			// 자원 정리
			executeClose(rs, pstmt, conn);
		}
		
		return count;
	}
	
	// 글 목록
	public List<BoardVO> getList(int startRow, int endRow) throws Exception { // 일반적으로 같은 클래스 내부에서만 사용할 때는 자료형을 ArrayList로, 외부에서 사용할 때는 자료형을 List로 지정
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs  = null;
		List<BoardVO> list = null;
		String sql = null;
		
		try {
			// 커넥션 풀로부터 커넥션을 할당
			conn = getConnection();
			
			// SQL문 작성
			sql = "SELECT * FROM (SELECT a.*, ROWNUM rnum FROM "
				+ "(SELECT * FROM sboard ORDER BY num DESC) a) "
				+ "WHERE rnum >= ? AND rnum <= ?";
			
			// PreparedStatement 객체 생성
			pstmt = conn.prepareStatement(sql);
			// ?에 데이터를 바인딩
			pstmt.setInt(1, startRow);
			pstmt.setInt(2, endRow);
			
			// SQL문을 실행해서 결과 행들을 ResultSet에 담아 반환
			rs = pstmt.executeQuery();
			
			// ArrayList 객체 생성
			list = new ArrayList<BoardVO>();
			while(rs.next()) {
				// 하나의 레코드 정보를 담기 위해 자바빈 객체 생성
				BoardVO boardVO = new BoardVO();
				boardVO.setNum(rs.getInt("num"));
				boardVO.setTitle(rs.getString("title"));
				boardVO.setName(rs.getString("name"));
				boardVO.setReg_date(rs.getDate("reg_date"));

				// 자바빈을 ArrayList에 등록
				list.add(boardVO);
			}
		}
		catch(Exception e) {
			throw new Exception(e);
		}
		finally {
			// 자원 정리
			executeClose(rs, pstmt, conn);
		}
		
		return list;
	}
	
	// 글 상세
	public BoardVO getBoard(int num) throws Exception {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		BoardVO board = null;
		String sql = null;
		
		try {
			// 커넥션 풀로부터 커넥션을 할당
			conn = getConnection();
			
			// SQL문 작성
			sql = "SELECT * FROM sboard WHERE num=?";
			
			// PreparedStatement 객체 생성
			pstmt = conn.prepareStatement(sql);
			// ?에 데이터를 바인딩
			pstmt.setInt(1, num);
			
			// SQL문을 실행해서 결과 행을 ResultSet에 담아 반환
			rs = pstmt.executeQuery();
			if(rs.next()) {
				board = new BoardVO();
				board.setNum(rs.getInt("num"));
				board.setTitle(rs.getString("title"));
				board.setName(rs.getString("name"));
				board.setPasswd(rs.getString("passwd"));
				board.setContent(rs.getString("content"));
				board.setIp(rs.getString("ip"));
				board.setReg_date(rs.getDate("reg_date"));
			}
		}
		catch(Exception e) {
			throw new Exception(e);
		}
		finally {
			// 자원 정리
			executeClose(rs, pstmt, conn);
		}
		
		return board;
	}
	
	// 글 수정
	public void update(BoardVO boardVO) throws Exception {
		Connection conn = null;
		PreparedStatement pstmt = null;
		String sql = null;
		
		try {
			// 커넥션 풀로부터 커넥션을 할당
			conn = getConnection();
			
			// SQL문 작성
			sql = "UPDATE sboard SET title=?, name=?, content=?, ip=?, reg_date=SYSDATE WHERE num=?";
			
			// PreparedStatement 객체 생성
			pstmt = conn.prepareStatement(sql);
			// ?에 데이터를 바인딩
			pstmt.setString(1, boardVO.getTitle());
			pstmt.setString(2, boardVO.getName());
			pstmt.setString(3, boardVO.getContent());
			pstmt.setString(4, boardVO.getIp());
			pstmt.setInt(5, boardVO.getNum());
			
			// SQL문 실행
			pstmt.executeUpdate();
		}
		catch(Exception e) {
			throw new Exception(e);
		}
		finally {
			// 자원 정리
			executeClose(null, pstmt, conn);
		}
	}
	
	// 글 삭제
	public void delete(int num) throws Exception {
		Connection conn = null;
		PreparedStatement pstmt = null;
		String sql = null;
		
		try {
			// 커넥션 풀로부터 커넥션 할당
			conn = getConnection();
			
			// SQL문 작성
			sql = "DELETE FROM sboard WHERE num=?";
			
			// PreparedStatement 객체 생성
			pstmt = conn.prepareStatement(sql);
			// ?에 데이터를 바인딩
			pstmt.setInt(1, num);
			
			// SQL문 실행
			pstmt.executeUpdate();
		}
		catch(Exception e) {
			throw new Exception(e);
		}
		finally {
			// 자원 정리
			executeClose(null, pstmt, conn);
		}
	}
}
UI
  1. webapp 폴더 오른쪽 클릭 후 새 폴더 views 생성하고 새 JSP 파일 list.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="kr.board.dao.BoardDAO" %>
<%@ page import="kr.board.vo.BoardVO" %>
<%@ page import="kr.util.PagingUtil" %>
<%@ page import="java.util.List" %>
<%
	// 선택한 페이지 번호
	String pageNum = request.getParameter("pageNum");
	if(pageNum==null) {
		pageNum = "1";
	}
	
	// 한 화면에 몇 개의 글(행, 레코드)을 보여줄지 지정
	int rowCount = 10;
	// 한 화면에 몇 개의 페이지 수를 보여줄지 지정
	int pageCount = 10;
	
	// 현재 선택한 페이지
	int currentPage = Integer.parseInt(pageNum);
	
	BoardDAO dao = BoardDAO.getInstance();
	// 총 레코드 수 구하기
	int count = dao.getCount();
	
	PagingUtil pagingUtil = new PagingUtil(currentPage, count, rowCount, pageCount, "list.jsp");
	
	List<BoardVO> list = null;
	if(count>0) {
		list = dao.getList(pagingUtil.getStartCount(), pagingUtil.getEndCount()); // PagingUtil의 메서드를 이용하여 시작 ROWNUM 번호, 끝 ROWNUM 번호를 전달
	}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판 목록</title>
<link rel="stylesheet" href="<%= request.getContextPath() %>/css/layout.css">
</head>
<body>
<div class="page-main">
	<h1>게시판 목록</h1>
	<div class="align-right">
		<input type="button" value="글쓰기" onclick="location.href = 'writeForm.jsp';">
	</div>
<%
	if(count==0) {
%>
	<div class="result-display">저장된 글이 없습니다.</div>
<%		
	}
	else {
%>
	<!-- 목록 출력 시작 -->
	<table>
		<tr>
			<th>글 번호</th>
			<th>제목</th>
			<th>작성자</th>
			<th>작성일</th>
		</tr>
<%
		for(BoardVO boardVO : list) {
%>
		<tr>
			<td><%= boardVO.getNum() %></td>
			<td><a href="detail.jsp?num=<%= boardVO.getNum() %>"><%= boardVO.getTitle() %></a></td> <%-- 회원 번호와 달리 글 번호는 세션에 저장하지 않으므로 GET 방식으로 전달 --%>
			<td><%= boardVO.getName() %></td>
			<td><%= boardVO.getReg_date() %></td>
		</tr>
<%		
		}
%>
	</table>
	<!-- 목록 출력 끝 -->
	<div class="align-center">
		<%= pagingUtil.getPagingHtml() %>
	</div>
<%
	}
%>
</div>
</body>
</html>
  1. 새 JSP 파일 writeForm.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글쓰기</title>
<link rel="stylesheet" href="<%= request.getContextPath() %>/css/layout.css">
<script type="text/javascript">
	window.onload = function() {
		document.getElementById('write_form').onsubmit = function() {
			let list = document.getElementsByTagName('li');
			for(let i=0;i<list.length;i++) {
				let input = list[i].querySelector('input,textarea');
				input.value = input.value.trim();
				if(!input.value) {
					let word = list[i].querySelector('label').textContent;
					let post = (word.charCodeAt(word.length-1) - ''.charCodeAt(0)) % 28 > 0 ? '' : '';
					alert(word + post + ' 입력하세요!');
					input.focus();
					return false;
				}
			}
		};
	};
</script>
</head>
<body>
<div class="page-main">
	<h1>글쓰기</h1>
	<form id="write_form" action="write.jsp" method="post">
		<ul>
			<li>
				<label for="title">제목</label>
				<input type="text" name="title" id="title" size="30" maxlength="50">
			</li>
			<li>
				<label for="name">작성자</label>
				<input type="text" name="name" id="name" size="10" maxlength="10">
			</li>
			<li>
				<label for="passwd">비밀번호</label>
				<input type="password" name="passwd" id="passwd" size="10" maxlength="12">
			</li>
			<li>
				<label for="content">내용</label>
				<textarea rows="5" cols="40" name="content" id="content"></textarea>
			</li>
		</ul>
		<div class="align-center">
			<input type="submit" value="글쓰기">
			<input type="button" value="목록" onclick="location.href = 'list.jsp';">
		</div>
	</form>
</div>
</body>
</html>
  1. 새 JSP 파일 write.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="kr.board.dao.BoardDAO" %>
<%
	// 전송된 데이터 인코딩 처리
	request.setCharacterEncoding("UTF-8");
%>
<jsp:useBean id="board" class="kr.board.vo.BoardVO"/>
<jsp:setProperty property="*" name="board"/>
<%
	// 클라이언트의 IP 주소 저장
	board.setIp(request.getRemoteAddr());

	BoardDAO dao = BoardDAO.getInstance();
	dao.insert(board);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글쓰기 완료</title>
<link rel="stylesheet" href="<%= request.getContextPath() %>/css/layout.css">
</head>
<body>
<div class="page-main">
	<h1>글쓰기 완료</h1>
	<div class="result-display">
		<div class="align-center">
			게시판에 글을 등록하였습니다.<br>
			<input type="button" value="목록" onclick="location.href = 'list.jsp';">
		</div>
	</div>
</div>
</body>
</html>
  1. 새 JSP 파일 deleteForm.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	int num = Integer.parseInt(request.getParameter("num"));
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글 삭제 폼</title>
<link rel="stylesheet" href="<%= request.getContextPath() %>/css/layout.css">
<script type="text/javascript">
	window.onload = function() {
		document.getElementById('delete_form').onsubmit = function() {
			var passwd = document.getElementById('passwd');
			if(passwd.value.trim()=='') {
				alert('비밀번호를 입력하세요!');
				passwd.value = '';
				passwd.focus();
				return false;
			}
		};
	};
</script>
</head>
<body>
<div class="page-main">
	<h1>글 삭제</h1>
	<form id="delete_form" action="delete.jsp" method="post">
		<input type="hidden" name="num" value="<%= num %>">
		<ul>
			<li>
				<label for="passwd">비밀번호</label>
				<input type="password" name="passwd" id="passwd" size="12" maxlength="12">
			</li>
		</ul>
		<div class="align-center">
			<input type="submit" value="글 삭제">
			<input type="button" value="목록" onclick="location.href = 'list.jsp';">
		</div>
	</form>
</div>
</body>
</html>
  1. 새 JSP 파일 delete.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="kr.board.dao.BoardDAO" %>
<%@ page import="kr.board.vo.BoardVO" %>
<%
	// 전송된 데이터 인코딩 처리
	request.setCharacterEncoding("UTF-8");

	// 전송된 데이터 반환
	int num = Integer.parseInt(request.getParameter("num"));
	String passwd = request.getParameter("passwd");
	
	BoardDAO dao = BoardDAO.getInstance();
	BoardVO db_board = dao.getBoard(num);
	boolean check = false;
	if(db_board!=null) {
		check = db_board.isCheckedPassword(passwd);
	}
	
	if(check) { // 인증 성공
		dao.delete(num); // 글 삭제
%>
	<script type="text/javascript">
		alert('글 삭제가 완료되었습니다.');
		location.href = 'list.jsp';
	</script>
<%
	}
	else { // 인증 실패
%>
	<script type="text/javascript">
		alert('비밀번호 불일치!');
		history.go(-1);
	</script>
<%
	}
%>

다음으로