Study Web Development

1월 24일

이전으로

Servlet & JSP

9. MVC

mvcBoard

프로젝트 생성 및 설정
  1. WEB-INF 폴더의 ActionMap.properties 하단에 다음의 내용을 추가
/detail.do=kr.board.action.DetailAction
/modifyForm.do=kr.board.action.ModifyFormAction
/modify.do=kr.board.action.ModifyAction
/deleteForm.do=kr.board.action.DeleteFormAction
/delete.do=kr.board.action.DeleteAction
# properties 파일의 경우, = 전후 공백은 무시하지만 클래스명 뒤의 공백은 클래스명으로 인식하므로 주의
Model
  1. 새 클래스 DetailAction 생성
package kr.board.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.board.dao.BoardDAO;
import kr.board.vo.BoardVO;
import kr.controller.Action;

public class DetailAction implements Action{

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		int num = Integer.parseInt(request.getParameter("num"));
		
		BoardDAO dao = BoardDAO.getInstance();
		BoardVO vo = dao.getBoard(num);
		
		request.setAttribute("vo", vo);
		
		return "/WEB-INF/views/detail.jsp";
	}
	
}
  1. 새 클래스 ModifyFormAction 생성
package kr.board.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.board.dao.BoardDAO;
import kr.controller.Action;

public class ModifyFormAction implements Action {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		request.setAttribute("vo", BoardDAO.getInstance().getBoard(Integer.parseInt(request.getParameter("num"))));
		
		// JSP 경로 반환
		return "/WEB-INF/views/modifyForm.jsp";
	}

}
  1. 새 클래스 ModifyAction 생성
package kr.board.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.board.dao.BoardDAO;
import kr.board.vo.BoardVO;
import kr.controller.Action;

public class ModifyAction implements Action {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// 전송된 데이터 인코딩 처리
		request.setCharacterEncoding("UTF-8");
		
		// 자바빈 객체 생성
		BoardVO vo = new BoardVO();
		vo.setNum(Integer.parseInt(request.getParameter("num")));
		vo.setTitle(request.getParameter("title"));
		vo.setName(request.getParameter("name"));
		vo.setPasswd(request.getParameter("passwd"));
		vo.setContent(request.getParameter("content"));
		vo.setIp(request.getRemoteAddr());
		
		BoardDAO dao = BoardDAO.getInstance();
		BoardVO db_vo = dao.getBoard(vo.getNum());
		boolean check = false;
		if(db_vo!=null) {
			// 비밀번호 일치 여부 체크
			check = db_vo.isCheckedPassword(vo.getPasswd());
		}
		
		if(check) {
			dao.update(vo);
		}
		
		request.setAttribute("check", check); // 화면 제어에 이용하기 위해 request 영역에 check 값 저장
		
		// JSP 경로 반환
		return "/WEB-INF/views/modify.jsp";
	}

}
  1. 새 클래스 DeleteFormAction 생성
package kr.board.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.controller.Action;

public class DeleteFormAction implements Action {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		request.setAttribute("num", Integer.parseInt(request.getParameter("num")));
		
		// JSP 경로 반환
		return "/WEB-INF/views/deleteForm.jsp";
	}

}
  1. 새 클래스 DeleteAction 생성
package kr.board.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.board.dao.BoardDAO;
import kr.board.vo.BoardVO;
import kr.controller.Action;

public class DeleteAction implements Action {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// 전송된 데이터 인코딩 처리
		request.setCharacterEncoding("UTF-8");
		
		int num = Integer.parseInt(request.getParameter("num"));
		String passwd = request.getParameter("passwd");
		
		BoardDAO dao = BoardDAO.getInstance();
		BoardVO db_vo = dao.getBoard(num);
		boolean check = false;
		if(db_vo!=null) {
			// 비밀번호 일치 여부 체크
			check = db_vo.isCheckedPassword(passwd);
		}

		if(check) {
			dao.delete(num);
		}
		
		request.setAttribute("check", check); // UI를 처리하기 위해 request 영역에 check 값 저장
		
		// JSP 경로 반환
		return "/WEB-INF/views/delete.jsp";
	}

}
View
  1. 새 JSP 파일 detail.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="${pageContext.request.contextPath}/css/layout.css">
<style type="text/css">
	hr {border-style: solid; color: gray;}
</style>
</head>
<body>
<div class="page-main">
	<h2>게시판 글 상세</h2>
	<ul>
		<li>
			<label>글 번호</label>
			${vo.num}
		</li>
		<li>
			<label>제목</label>
			${vo.title}
		</li>
		<li>
			<label>작성자</label>
			${vo.name}
		</li>
	</ul>
	<hr>
	<p>
		${vo.content}
	</p>
	<hr>
	<div class="align-right">
		작성일 : ${vo.reg_date}
		<input type="button" value="수정" onclick="location.href = 'modifyForm.do?num=${vo.num}';">
		<input type="button" value="삭제" onclick="location.href = 'deleteForm.do?num=${vo.num}';">
		<input type="button" value="목록" onclick="location.href = 'list.do';">
	</div>
</div>
</body>
</html>
  1. 새 JSP 파일 modifyForm.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="${pageContext.request.contextPath}/css/layout.css">
</head>
<body>
<div class="page-main">
	<h2>글 수정</h2>
	<form id="modify_form" action="modify.do" method="post">
		<input type="hidden" name="num" value="${vo.num}">
		<ul>
			<li>
				<label for="title">제목</label>
				<input type="text" name="title" id="title" value="${vo.title}" size="30">
			</li>
			<li>
				<label for="name">이름</label>
				<input type="text" name="name" id="name" value="${vo.name}" size="10">
			</li>
			<li>
				<label for="passwd">비밀번호</label>
				<input type="password" name="passwd" id="passwd" size="12"> * 등록시 입력한 비밀번호
			</li>
			<li>
				<label for="content">내용</label>
				<textarea rows="5" cols="40" name="content" id="content">${vo.content}</textarea>
			</li>
		</ul>
		<div class="align-center">
			<input type="submit" value="수정">
			<input type="button" value="목록" onclick="location.href = 'list.do';">
		</div>
	</form>
</div>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/validateLength.js"></script>
<script type="text/javascript">
	validateSubmit('modify_form');
	validateBytesLength({title:150,name:30,passwd:12});
</script>
</body>
</html>
  1. 새 JSP 파일 modify.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:if test="${check}">
	<script type="text/javascript">
		alert('글 수정을 완료하였습니다.');
		location.href = 'list.do';
	</script>
</c:if>
<c:if test="${!check}">
	<script type="text/javascript">
		alert('비밀번호 불일치!');
		history.go(-1);
	</script>
</c:if>
  1. 새 JSP 파일 deleteForm.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="${pageContext.request.contextPath}/css/layout.css">
</head>
<body>
<div class="page-main">
	<h2>글 삭제</h2>
	<form id="delete_form" action="delete.do" method="post">
		<input type="hidden" name="num" value="${num}"> <%-- 클래스에서 request 영역에 속성을 저장하지 않고 ${param.num}을 사용하는 것도 가능 --%>
		<ul>
			<li>
				<label for="passwd">비밀번호</label>
				<input type="password" name="passwd" id="passwd" size="12">
			</li>
		</ul>
		<div class="align-center">
			<input type="submit" value="삭제">
			<input type="button" value="목록" onclick="location.href = 'list.do';">
		</div>
	</form>
</div>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/validateLength.js"></script>
<script type="text/javascript">
	validateSubmit('delete_form');
	validateBytesLength({passwd:12});
</script>
</body>
</html>
  1. 새 JSP 파일 delete.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<script type="text/javascript">
	if(${check}) {
		alert('글 삭제를 완료하였습니다.');
		location.href = 'list.do';
	}
	else {
		alert('비밀번호 불일치!');
		history.go(-1);
	}
</script>

mvcProduct

프로젝트 생성 및 설정
  1. 새 다이나믹 웹 프로젝트를 생성하여 프로젝트명에 mvcProduct 입력 후 Next-Next-Generate web.xml depolyment descriptor 선택 후 Finish
  2. 프로젝트를 오른쪽 클릭하여 Build Path-Configure Build Path... 선택하고 Libraries 탭에서 JRE System Library를 선택 후 Edit...에서 Workspace default JRE로 변경
  3. WEB-INF 폴더의 web.xml를 열고, 왼쪽 하단의 Source 탭 선택
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>mvcProduct</display-name>
  <servlet>
  	<servlet-name>DispatcherServlet</servlet-name>
  	<servlet-class>kr.controller.DispatcherServlet</servlet-class>
  	<init-param>
  		<param-name>propertiesPath</param-name>
  		<param-value>/WEB-INF/ActionMap.properties</param-value>
  	</init-param>
  </servlet>
  <servlet-mapping>
  	<servlet-name>DispatcherServlet</servlet-name>
  	<url-pattern>*.do</url-pattern>
  </servlet-mapping>
  <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>
</web-app>
  1. WEB-INF 폴더 오른쪽 클릭하고 새 파일 ActionMap.properties 생성
/list.do=kr.product.action.ListAction
/writeForm.do=kr.product.action.WriteFormAction
/write.do=kr.product.action.WriteAction
/detail.do=kr.product.action.DetailAction
/modifyForm.do=kr.product.action.ModifyFormAction
/modify.do=kr.product.action.ModifyAction
/deleteForm.do=kr.product.action.DeleteFormAction
/delete.do=kr.product.action.DeleteAction
  1. C:\javaWork\apps에서 ojdbc8.jar, jstl-1.2.jar를 복사하여 mvcProduct 프로젝트의 src/main/webapp/WEB-INF/lib 폴더에 붙여넣기
  2. mvcBoard 프로젝트의 src/main/webapp/META-INF 폴더에서 context.xml을 복사하여 mvcProduct 프로젝트의 src/main/webapp/META-INF 폴더에 붙여넣기
  3. src/main/java 오른쪽 클릭하여 새 패키지 kr.controller 생성
  4. mvcBoard 프로젝트의 kr.controller 패키지에서 DispatcherServlet.java, Action.java를 복사하여 mvcProduct 프로젝트의 kr.controller 패키지에 붙여넣기
  5. src/main/java 오른쪽 클릭하여 새 패키지 kr.util 생성
  6. mvcBoard 프로젝트의 kr.util 패키지에서 PagingUtil.java를 복사하여 mvcProduct 프로젝트의 kr.util 패키지에 붙여넣기
  7. webapp 폴더 오른쪽 클릭하고 새 JSP 파일 index.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	response.sendRedirect(request.getContextPath() + "/list.do");
%>
  1. mvcBoard 프로젝트의 src/main/webapp 폴더에서 css 폴더를 복사하여 mvcProduct 프로젝트의 src/main/webapp 폴더에 붙여넣기
  2. mvcBoard 프로젝트의 src/main/webapp 폴더에서 js 폴더를 복사하여 mvcProduct 프로젝트의 src/main/webapp 폴더에 붙여넣기
  3. m1_product 프로젝트의 src/main/webapp 폴더에서 sql 폴더를 복사하여 mvcProduct 프로젝트의 src/main/webapp 폴더에 붙여넣기
Model
  1. src/main/java 오른쪽 클릭하고 새 패키지 kr.product.action 생성 후 새 클래스 ListAction 생성
package kr.product.action;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.controller.Action;
import kr.product.dao.ProductDAO;
import kr.product.vo.ProductVO;
import kr.util.PagingUtil;

public class ListAction implements Action {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String pageNum = request.getParameter("pageNum");
		if(pageNum==null) pageNum = "1";
		
		ProductDAO dao = ProductDAO.getInstance();
		int totalCount = dao.getCount();

		// 페이지 처리
		PagingUtil pg = new PagingUtil(Integer.parseInt(pageNum), totalCount, 20, 10, "list.do");
		
		List<ProductVO> list = null;
		if(totalCount>0) {
			list = dao.getList(pg.getStartCount(), pg.getEndCount());	
		}

		// 데이터를 request에 저장
		request.setAttribute("list", list);
		request.setAttribute("pagingHtml", pg.getPagingHtml());
		request.setAttribute("totalCount", totalCount);
		
		// JSP 경로 반환
		return "/WEB-INF/views/list.jsp";
	}

}
  1. 새 클래스 WriteFormAction 생성
package kr.product.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.controller.Action;

public class WriteFormAction implements Action {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// JSP 경로 반환
		return "/WEB-INF/views/writeForm.jsp";
	}

}
  1. 새 클래스 WriteAction 생성
package kr.product.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.controller.Action;
import kr.product.dao.ProductDAO;
import kr.product.vo.ProductVO;

public class WriteAction implements Action {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// 전송된 데이터 인코딩 처리
		request.setCharacterEncoding("UTF-8");
		
		// 자바빈 생성
		ProductVO vo = new ProductVO();
		
		// 전송된 데이터를 자바빈에 저장
		vo.setName(request.getParameter("name"));
		vo.setPrice(Integer.parseInt(request.getParameter("price")));
		vo.setStock(Integer.parseInt(request.getParameter("stock")));
		vo.setOrigin(request.getParameter("origin"));
		vo.setContent(request.getParameter("content"));
		
		// DAO 호출
		ProductDAO.getInstance().registerProduct(vo);
		
		// JSP 경로 반환
		return "/WEB-INF/views/write.jsp";
	}

}
  1. 새 클래스 DetailAction 생성
package kr.product.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.controller.Action;
import kr.product.dao.ProductDAO;

public class DetailAction implements Action {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		request.setAttribute("vo", ProductDAO.getInstance().getProduct(Integer.parseInt(request.getParameter("num"))));
		
		// JSP 경로 반환
		return "/WEB-INF/views/detail.jsp";
	}

}
  1. 새 클래스 ModifyFormAction 생성
package kr.product.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.controller.Action;
import kr.product.dao.ProductDAO;

public class ModifyFormAction implements Action {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		request.setAttribute("vo", ProductDAO.getInstance().getProduct(Integer.parseInt(request.getParameter("num"))));
		
		// JSP 경로 반환
		return "/WEB-INF/views/modifyForm.jsp";
	}

}
  1. 새 클래스 ModifyAction 생성
package kr.product.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.controller.Action;
import kr.product.dao.ProductDAO;
import kr.product.vo.ProductVO;

public class ModifyAction implements Action {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// 전송된 데이터 인코딩 처리
		request.setCharacterEncoding("UTF-8");
		
		// 자바빈 생성
		ProductVO vo = new ProductVO();
		
		// 전송된 데이터를 자바빈에 저장
		vo.setNum(Integer.parseInt(request.getParameter("num")));
		vo.setName(request.getParameter("name"));
		vo.setPrice(Integer.parseInt(request.getParameter("price")));
		vo.setStock(Integer.parseInt(request.getParameter("stock")));
		vo.setOrigin(request.getParameter("origin"));
		vo.setContent(request.getParameter("content"));
		
		// DAO 호출
		ProductDAO.getInstance().updateProduct(vo);
		
		// JSP 경로 반환
		return "/WEB-INF/views/modify.jsp";
	}

}
  1. 새 클래스 DeleteFormAction 생성
package kr.product.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.controller.Action;

public class DeleteFormAction implements Action {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// JSP 경로 반환
		return "/WEB-INF/views/deleteForm.jsp";
	}

}
  1. 새 클래스 DeleteAction 생성
package kr.product.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.controller.Action;
import kr.product.dao.ProductDAO;

public class DeleteAction implements Action {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		ProductDAO.getInstance().deleteProduct(Integer.parseInt(request.getParameter("num")));
		
		// JSP 경로 반환
		return "/WEB-INF/views/delete.jsp";
	}

}
View
  1. WEB-INF 폴더 오른쪽 클릭하고 새 폴더 views 생성 후 새 JSP 파일 list.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>상품 목록</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/layout.css">
</head>
<body>
<div class="page-main">
	<h2>상품 목록</h2>
	<div class="align-right">
		<input type="button" value="등록" onclick="location.href = 'writeForm.do';">
	</div>
	<c:if test="${totalCount == 0}">
	<div class="result-display">
		상품 정보가 없습니다!
	</div>
	</c:if>
	<c:if test="${totalCount > 0}">
	<table>
		<tr>
			<th>상품 번호</th>
			<th>상품명</th>
			<th>가격 (원)</th>
			<th>재고 (개)</th>
			<th>원산지</th>
			<th>등록일</th>
		</tr>
		<c:forEach var="vo" items="${list}">
		<tr>
			<td>${vo.num}</td>
			<td><a href="detail.do?num=${vo.num}">${vo.name}</a></td>
			<td>${String.format("%,d", vo.price)}</td>
			<td>${String.format("%,d", vo.stock)}</td>
			<td>${vo.origin}</td>
			<td>${vo.reg_date}</td>
		</tr>
		</c:forEach>
	</table>
	<div class="align-center">
		${pagingHtml}
	</div>
	</c:if>
</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="${pageContext.request.contextPath}/css/layout.css">
</head>
<body>
<div class="page-main">
	<h2>상품 등록</h2>
	<form id="form" action="write.do" method="post">
		<ul>
			<li>
				<label for="name">상품명</label>
				<input type="text" name="name" id="name" size="10">
			</li>
			<li>
				<label for="price">가격</label>
				<input type="number" name="price" id="price" min="1">
			</li>
			<li>
				<label for="stock">재고</label>
				<input type="number" name="stock" id="stock" min="0">
			</li>
			<li>
				<label for="origin">원산지</label>
				<input type="text" name="origin" id="origin" size="10">
			</li>
			<li>
				<label for="content">설명</label>
				<textarea rows="5" cols="40" name="content"></textarea>
			</li>
		</ul>
		<div class="align-center">
			<input type="submit" value="등록">
			<input type="button" value="목록" onclick="location.href = 'list.do';">
		</div>
	</form>
</div>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/validateLength.js"></script>
<script type="text/javascript">
	validateSubmit('form');
	validateBytesLength({name:30,price:9,stock:9,origin:30});
</script>
</body>
</html>
  1. 새 JSP 파일 write.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<script type="text/javascript">
	alert('상품 등록을 완료하였습니다');
	location.href = 'list.do';
</script>
  1. 새 JSP 파일 detail.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="${pageContext.request.contextPath}/css/layout.css">
<style type="text/css">
	hr {border-style: solid; color: gray;}
</style>
</head>
<body>
<div class="page-main">
	<h2>상품 상세 정보</h2>
	<ul>
		<li>
			<label>상품 번호</label>
			${vo.num}
		</li>
		<li>
			<label>상품명</label>
			${vo.name}
		</li>
		<li>
			<label>가격</label>
			${String.format("%,d원", vo.price)}
		</li>
		<li>
			<label>재고</label>
			${String.format("%,d개", vo.stock)}
		</li>
		<li>
			<label>원산지</label>
			${vo.origin}
		</li>
		<li>
			<label>등록일</label>
			${vo.reg_date}
		</li>
	</ul>
	<hr>
	<p>
		${vo.content}
	</p>
	<hr>
	<div class="align-right">
		<input type="button" value="수정" onclick="location.href = 'modifyForm.do?num=${vo.num}';">
		<input type="button" value="삭제" onclick="location.href = 'deleteForm.do?num=${vo.num}';">
		<input type="button" value="목록" onclick="location.href = 'list.do';">
	</div>
</div>
</body>
</html>
  1. 새 JSP 파일 modifyForm.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="${pageContext.request.contextPath}/css/layout.css">
</head>
<body>
<div class="page-main">
	<h2>상품 수정</h2>
	<form id="form" action="modify.do" method="post">
		<input type="hidden" name="num" value="${vo.num}">
		<ul>
			<li>
				<label for="name">상품명</label>
				<input type="text" name="name" id="name" size="10" value="${vo.name}">
			</li>
			<li>
				<label for="price">가격</label>
				<input type="number" name="price" id="price" min="1" value="${vo.price}">
			</li>
			<li>
				<label for="stock">재고</label>
				<input type="number" name="stock" id="stock" min="0" value="${vo.stock}">
			</li>
			<li>
				<label for="origin">원산지</label>
				<input type="text" name="origin" id="origin" size="10" value="${vo.origin}">
			</li>
			<li>
				<label for="content">설명</label>
				<textarea rows="5" cols="40" name="content">${vo.content}</textarea>
			</li>
		</ul>
		<div class="align-center">
			<input type="submit" value="수정">
			<input type="button" value="목록" onclick="location.href = 'list.do';">
		</div>
	</form>
</div>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/validateLength.js"></script>
<script type="text/javascript">
	validateSubmit('form');
	validateBytesLength({name:30,price:9,stock:9,origin:30});
</script>
</body>
</html>
  1. 새 JSP 파일 modify.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<script type="text/javascript">
	alert('상품 정보를 수정하였습니다');
	location.href = 'list.do';
</script>
  1. 새 JSP 파일 deleteForm.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="${pageContext.request.contextPath}/css/layout.css">
</head>
<body>
<div class="page-main">
	<h2>상품 정보 삭제</h2>
	<form action="delete.do" method="post">
		<input type="hidden" name="num" value="${param.num}">
		<div class="align-center">
			<p>
				정말 삭제하시겠습니까?
			</p>
			<input type="submit" value="삭제">
			<input type="button" value="목록" onclick="location.href = 'list.do';">
		</div>
	</form>
</div>
</body>
</html>
  1. 새 JSP 파일 delete.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<script type="text/javascript">
	alert('상품 정보를 삭제하였습니다')
	location.href = 'list.do';
</script>
자바빈
  1. src/main/java 오른쪽 클릭하여 새 패키지 kr.product.vo 생성 후 새 클래스 ProductVO 생성
package kr.product.vo;

import java.sql.Date;

public class ProductVO {
	private int num; // 상품 번호
	private String name; // 상품명
	private int price; // 가격
	private int stock; // 재고
	private String origin; // 원산지
	private String content; // 설명
	private Date reg_date; // 등록일
	
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	public int getStock() {
		return stock;
	}
	public void setStock(int stock) {
		this.stock = stock;
	}
	public String getOrigin() {
		return origin;
	}
	public void setOrigin(String origin) {
		this.origin = origin;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	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.product.dao 생성 후 새 클래스 ProductDAO 생성
package kr.product.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.product.vo.ProductVO;

public class ProductDAO {

	// 싱글턴 패턴
	private static ProductDAO instance = new ProductDAO();
	public static ProductDAO getInstance() {
		return instance;
	}
	private ProductDAO() {}
	
	// 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 registerProduct(ProductVO vo) throws Exception {
		Connection conn = null;
		PreparedStatement pstmt = null;
		String sql = null;
		
		try {
			conn = getConnection();
			
			sql = "INSERT INTO sproduct (num, name, price, stock, origin, content) "
				+ "VALUES (sproduct_seq.NEXTVAL, ?, ?, ?, ?, ?)";
			
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, vo.getName());
			pstmt.setInt(2, vo.getPrice());
			pstmt.setInt(3, vo.getStock());
			pstmt.setString(4, vo.getOrigin());
			pstmt.setString(5, vo.getContent());
			
			pstmt.executeUpdate();
		}
		catch(Exception e) {
			throw new Exception(e);
		}
		finally {
			executeClose(null, pstmt, conn);
		}
	}
	
	// 총 상품 수
	public int getCount() throws Exception {
		int count = 0;
		
		Connection conn = null;
		PreparedStatement pstmt =  null;
		ResultSet rs = null;
		String sql= null;
		
		try {
			conn = getConnection();
			
			sql = "SELECT COUNT(*) FROM sproduct";
			
			pstmt = conn.prepareStatement(sql);
			
			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<ProductVO> getList(int startRow, int endRow) throws Exception {
		List<ProductVO> list = null;
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String sql= null;
		
		try {
			conn = getConnection();
			
			sql = "SELECT * FROM (SELECT sp.*, ROWNUM AS rnum "
				+ "FROM (SELECT * FROM sproduct ORDER BY num DESC) sp) "
				+ "WHERE rnum >= ? AND rnum <= ?";
			
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, startRow);
			pstmt.setInt(2, endRow);
			
			rs = pstmt.executeQuery();
			list = new ArrayList<ProductVO>();
			while(rs.next()) {
				ProductVO vo = new ProductVO();
				vo.setNum(rs.getInt("num"));
				vo.setName(rs.getString("name"));
				vo.setPrice(rs.getInt("price"));
				vo.setStock(rs.getInt("stock"));
				vo.setOrigin(rs.getString("origin"));
				vo.setReg_date(rs.getDate("reg_date"));
				
				list.add(vo);
			}
		}
		catch(Exception e) {
			throw new Exception(e);
		}
		finally {
			executeClose(rs, pstmt, conn);
		}
		
		return list;
	}
	
	// 상품 상세 정보
	public ProductVO getProduct(int num) throws Exception {
		ProductVO vo = null;
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String sql= null;
		
		try {
			conn = getConnection();
			
			sql = "SELECT * FROM sproduct WHERE num=?";
			
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, num);
			
			rs = pstmt.executeQuery();
			if(rs.next()) {
				vo = new ProductVO();
				vo.setNum(num);
				vo.setName(rs.getString("name"));
				vo.setPrice(rs.getInt("price"));
				vo.setStock(rs.getInt("stock"));
				vo.setOrigin(rs.getString("origin"));
				vo.setContent(rs.getString("content"));
				vo.setReg_date(rs.getDate("reg_date"));
			}
		}
		catch(Exception e) {
			throw new Exception(e);
		}
		finally {
			executeClose(rs, pstmt, conn);
		}
		
		return vo;
	}
	
	// 상품 수정
	public void updateProduct(ProductVO vo) throws Exception {
		Connection conn = null;
		PreparedStatement pstmt = null;
		String sql = null;
		
		try {
			conn = getConnection();
			
			sql = "UPDATE sproduct SET name=?, price=?, stock=?, origin=?, content=? WHERE num=?";
			
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, vo.getName());
			pstmt.setInt(2, vo.getPrice());
			pstmt.setInt(3, vo.getStock());
			pstmt.setString(4, vo.getOrigin());
			pstmt.setString(5, vo.getContent());
			pstmt.setInt(6, vo.getNum());
			
			pstmt.executeUpdate();
		}
		catch(Exception e) {
			throw new Exception(e);
		}
		finally {
			executeClose(null, pstmt, conn);
		}
	}
	
	// 상품 삭제
	public void deleteProduct(int num) throws Exception {
		Connection conn = null;
		PreparedStatement pstmt = null;
		String sql = null;
		
		try {
			conn = getConnection();
			
			sql = "DELETE FROM sproduct WHERE num=?";
			
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, num);
			
			pstmt.executeUpdate();
		}
		catch(Exception e) {
			throw new Exception(e);
		}
		finally {
			executeClose(null, pstmt, conn);
		}
	}
}

다음으로