일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- opener
- session.removeAttribute
- Alert
- 팝업창
- 데이터사이언스
- 자바빈즈
- 파일 호출
- static
- 빈즈
- 동기 부여
- scanner
- 파일호출
- 동기부여
- 영감
- ;
- session.setAttribute
- Import
- target
- session.getAttribute
- 페이지이동
- 미래직장
- 로그인화면
- 향상된 for문
- 버리자
- "
- \
- 페이지 이동
- javaBeans
- iframe
- BEANS
- Today
- Total
갈림길 이정표
[JSP] (최종 - Model Ⅰ방식) 간단한 쇼핑몰 게시판 만들어 보기 *갱신 필* 본문
[JSP] (최종 - Model Ⅰ방식) 간단한 쇼핑몰 게시판 만들어 보기 *갱신 필*
이몽뇽 2020. 9. 2. 22:43출처: cafe.daum.net/flowlife/HqLp/13
다음은 쇼핑몰 게시판을 만들기 위한 간단한 Mind Map이다. (나중에 Q&A로 활용 가능)

보통의 게시판이라면 위와 같이 간단하게 구조화 시킬 수 있다. 우리는 이런 기본적인 구조를 구현할 수 있으면 된다.
(추가적인 부분은 나중에 연구해서 구현해보도록 하자)
※ 이번 글은 각 기능 별 구현하는 방법에 대해 자세하게 다루기 위해 전반적인 코딩은 숨김으로 표시 해놓았다.
▽ web_myshop 사이드 바 목록

▽구현을 위한 기본 java source 파일들
▼ DB 레코드에 대한 각 칼럼별 getter와 setter ( + jsp 액션 태그 中 setProperty를 쓰기 위함, INSERT용)
(※ setBdate 메소드 만큼은 Overloading 하였으니 주의)
[BoardBean.java]
package kr.shop.board;
import java.util.Calendar;
public class BoardBean { //form bean
private String name, pass, mail, title, cont, bip, bdate;
private int num, readcnt, gnum, onum, nested;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getCont() {
return cont;
}
public void setCont(String cont) {
this.cont = cont;
}
public String getBip() {
return bip;
}
public void setBip(String bip) {
this.bip = bip;
}
public String getBdate() {
return bdate;
}
public void setBdate(String bdate) {
this.bdate = bdate;
}
public void setBdate() { //Overloading
Calendar cal = Calendar.getInstance(); //Singleton 패턴
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH) + 1;
int day = cal.get(Calendar.DATE);
this.bdate = year + "-" + month + "-" + day; //int로 받았지만 hyphen(-) 때문에 String으로 [Promotion]
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public int getReadcnt() {
return readcnt;
}
public void setReadcnt(int readcnt) {
this.readcnt = readcnt;
}
public int getGnum() {
return gnum;
}
public void setGnum(int gnum) {
this.gnum = gnum;
}
public int getOnum() {
return onum;
}
public void setOnum(int onum) {
this.onum = onum;
}
public int getNested() {
return nested;
}
public void setNested(int nested) {
this.nested = nested;
}
}
▼ DB 레코드에 대한 각 칼럼별 getter와 setter (SELECT, UPDATE, DELETE용)
[BoardDTO.java]
package kr.shop.board;
public class BoardDTO {
private String name, pass, mail, title, cont, bip, bdate;
private int num, readcnt, gnum, onum, nested;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getCont() {
return cont;
}
public void setCont(String cont) {
this.cont = cont;
}
public String getBip() {
return bip;
}
public void setBip(String bip) {
this.bip = bip;
}
public String getBdate() {
return bdate;
}
public void setBdate(String bdate) {
this.bdate = bdate;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public int getReadcnt() {
return readcnt;
}
public void setReadcnt(int readcnt) {
this.readcnt = readcnt;
}
public int getGnum() {
return gnum;
}
public void setGnum(int gnum) {
this.gnum = gnum;
}
public int getOnum() {
return onum;
}
public void setOnum(int onum) {
this.onum = onum;
}
public int getNested() {
return nested;
}
public void setNested(int nested) {
this.nested = nested;
}
}
Q. 왜 javaBeans파일과 DTO파일은 비슷한데 따로 만드나요?
A. 공통점: <jsp:useBean/> 액션태그로 각각의 파일들이 DB connection 파일 (dbcp 또는 Driver연결 파일)과 연결하여 사용.
차이점:
▣ javaBeans파일: <jsp:setProperty/>액션태그를 위해 사용.(post 방식의 넘겨받은 <form> tag정보들을 바로 javaBeans파일의 setter로 적용시키는 기법). 보통 사용자(User)로 부터 얻은 데이터 레코드를 DB에 저장해야 할 때, 오직 Business Logic을 위한 JSP 파일 (<HTML> tag 없음)에서만 사용됨. DAO(Data Access Object) 中 INSERT 작업을 위함. (∴ 사용자 입력 자료 DB 저장할 때, dbcp에서 Bean클래스 argument 필요.)
▣ DTO(Data Transfer Object) 파일: <jsp:setProperty/> 액션 태그를 사용할 수 없으므로 따로 request.getParameter( )으로 필요 정보를 받아와야 되며, setter보단 getter를 많이 사용함. DAO(Data Access Object) 中 SELECT, UPDATE, DELETE 작업을 위함.(∴ DB로 부터 데이터를 읽어와야 될 때)
▽DAO(Data Access Object)를 위한 자바 클래스 파일 (ing...)
[BoardMgr.java]
package kr.shop.board;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
public class BoardMgr { //Business logic
private Connection conn;
private PreparedStatement pstmt;
private ResultSet rs;
private DataSource ds;
private int tot; // 전체 레코드 수
private int pList = 10; //한 페이지 당 출력 행 수 (여기서 나중에 page당 몇 개씩 보기 옵션을 설정할 수 도 있음)
private int pageSu; // 전체 페이지 수
public BoardMgr() {
try {
Context context = new InitialContext();
ds = (DataSource)context.lookup("java:comp/env/jdbc_maria"); //JDBC Pooling
} catch (Exception e) {
System.out.println("BoardMgr err: " + e);
}
}
public ArrayList<BoardDTO> getDataAll(int page, String stype, String sword){
ArrayList<BoardDTO> list = new ArrayList<BoardDTO>();
//String sql = "SELECT * FROM shopboard ORDER BY gnum DESC, onum ASC";
String sql = "SELECT * FROM shopboard"; //검색이 있는 경우를 위해
try {
conn = ds.getConnection();
if(sword == null) { //검색이 없는 경우
sql += " ORDER BY gnum DESC, onum ASC";
pstmt = conn.prepareStatement(sql);
}else { //검색이 있는 경우
sql += " WHERE " + stype + " like ?"; //띄어 쓰기 주의
sql += " ORDER BY gnum DESC, onum ASC";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "%" + sword + "%");
}
rs = pstmt.executeQuery();
//5행씩 paging 처리
for (int i = 0; i < (page - 1) * pList; i++) {
rs.next(); //레코드 포인터 위치 (1 page → pointer: 0, 2 page → pointer: 4, 3 page → pointer: 9, ...)
//0이 첫번째 레코드, 4는 5번째 레코드
}
int k = 0; //임의 변수 (여기서 나중에 page당 몇 개씩 보기 옵션을 설정할 수 도 있음)
while(rs.next() && k < pList) {
BoardDTO dto = new BoardDTO();
dto.setNum(rs.getInt("num"));
dto.setName(rs.getString("name"));
dto.setTitle(rs.getString("title"));
dto.setBdate(rs.getString("bdate"));
dto.setReadcnt(rs.getInt("readcnt"));
dto.setNested(rs.getInt("nested"));
list.add(dto);
k++; //← 이게 추가됨
}
} catch (Exception e) {
System.out.println("getDataAll() err: " + e);
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception e2) {
}
}
return list;
}
public int currentGetNum() { //새 글 최대번호 구하기
String sql = "SELECT MAX(num) FROM shopboard";
int cnt = 0;
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
if(rs.next()) cnt = rs.getInt(1); //결과 값이 하나 이므로 if (없으면 0 값으로 return 하도록)
} catch (Exception e) {
System.out.println("currentGetNum() err: " + e);
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception e2) {
}
}
return cnt;
}
public void saveData(BoardBean bean) {
String sql = "INSERT INTO shopboard VALUES(?,?,?,?,?,?,?,?,?,?,?,?)";
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, bean.getNum());
pstmt.setString(2, bean.getName());
pstmt.setString(3, bean.getPass());
pstmt.setString(4, bean.getMail());
pstmt.setString(5, bean.getTitle());
pstmt.setString(6, bean.getCont());
pstmt.setString(7, bean.getBip());
pstmt.setString(8, bean.getBdate());
pstmt.setInt(9, 0); //readcnt
pstmt.setInt(10, bean.getGnum());
pstmt.setInt(11, 0); //onum (원글 이므로 0)
pstmt.setInt(12, 0); //nested (원글 이므로 0)
pstmt.executeUpdate();
rs = pstmt.executeQuery();
} catch (Exception e) {
System.out.println("saveData() err: " + e);
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception e2) {
}
}
}
public void totalList() {
String sql = "SELECT COUNT(*) FROM shopboard";
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
rs.next();
tot = rs.getInt(1);
//System.out.println("전체 건수 : " + tot);
} catch (Exception e) {
System.out.println("totalList() err: " + e);
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception e2) {
}
}
}
public int getPageSu() {
pageSu = tot / pList; //몫 정수값이 나옴
if(tot % pList > 0) pageSu++; //자투리 행 계산 (Ex. tot = 12행 일 때 (pList=5로 나누면) pageSu = 몫:2 나머지 2)
return pageSu; //pageSu: 몫 + (나머지) :3
}
public void updateReadcnt(String num) { //(글 내용 보기전) 조회수 증가
String sql = "UPDATE shopboard SET readcnt=readcnt +1 WHERE num = ?";
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, num);
pstmt.executeQuery(); //(값을 받아올 필요가 없어서) rs 필요 없음
} catch (Exception e) {
System.out.println("updateReadcnt() err: " + e);
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception e2) {
}
}
}
public BoardDTO getData(String num) {
String sql = "SELECT * FROM shopboard WHERE num =?";
BoardDTO dto = null;
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, num);
rs = pstmt.executeQuery();
if(rs.next()) { //있다 없다 여부
dto = new BoardDTO();
dto.setNum(Integer.parseInt(num));
dto.setName(rs.getString("name"));
dto.setPass(rs.getString("pass"));
dto.setMail(rs.getString("mail"));
dto.setTitle(rs.getString("title"));
dto.setCont(rs.getString("cont"));
dto.setBip(rs.getString("bip"));
dto.setBdate(rs.getString("bdate"));
dto.setReadcnt(rs.getInt("readcnt"));
}
} catch (Exception e) {
System.out.println("getData() err: " + e);
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception e2) {
}
}
return dto;
}
public BoardDTO getReplyData(String num) { //댓글용
BoardDTO dto = null;
String sql = "SELECT * FROM shopboard WHERE num = ?";
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, num);
rs = pstmt.executeQuery();
if(rs.next()) {
dto = new BoardDTO();
dto.setTitle(rs.getString("title"));
dto.setGnum(rs.getInt("gnum")); //group number
dto.setOnum(rs.getInt("onum")); //order number
dto.setNested(rs.getInt("nested")); //공백
}
} catch (Exception e) {
System.out.println("getReplyData() err: " + e);
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception e2) {
}
}
return dto;
}
public void updateOnum(int gnum, int onum) { //댓글용 - onum갱신
//같은 그룹의 레코드는 모두 작업에 참여 - 같은 그룹의 onum 값 변경
String sql = "UPDATE shopboard SET onum = onum +1 WHERE onum >= ? and gnum = ?";
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, onum);
pstmt.setInt(2, gnum);
pstmt.executeQuery(); //(값을 받아올 필요가 없어서) rs 필요 없음
} catch (Exception e) {
System.out.println("updateOnum() err: " + e);
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception e2) {
}
}
}
public void saveReplyData(BoardBean bean) { //댓글용 - DB 저장
String sql = "INSERT INTO shopboard VALUES(?,?,?,?,?,?,?,?,?,?,?,?)";
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, bean.getNum());
pstmt.setString(2, bean.getName());
pstmt.setString(3, bean.getPass());
pstmt.setString(4, bean.getMail());
pstmt.setString(5, bean.getTitle());
pstmt.setString(6, bean.getCont());
pstmt.setString(7, bean.getBip());
pstmt.setString(8, bean.getBdate());
pstmt.setInt(9, 0); //readcnt
pstmt.setInt(10, bean.getGnum());
pstmt.setInt(11, bean.getOnum()); //onum
pstmt.setInt(12, bean.getNested()); //nested
pstmt.executeUpdate();
} catch (Exception e) {
System.out.println("saveReplyData() err: " + e);
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception e2) {
}
}
}
}
[index.html]
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
HOME<p/>
메뉴1 메뉴2 <a href="board/boardlist.jsp">게시판</a>
</body>
</html>
▽ ing...
[boardlist.jsp]
<%@page import="kr.shop.board.BoardDTO"%>
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
int pageBlock, start, end; //페이징 처리를 위한 작업 (블럭단위)
int pageSu, spage = 1; //페이징 처리를 위한 작업 (페이지단위)
%>
<jsp:useBean id="boardMgr" class="kr.shop.board.BoardMgr"/>
<jsp:useBean id="dto" class="kr.shop.board.BoardDTO"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판</title>
<link rel="stylesheet" type="text/css" href="../css/board.css">
<script type="text/javascript">
window.onload = function(){
document.getElementById("btnSearch").onclick = function(){
if(frm.sword.value === ""){
frm.sword.focus();
alert("검색어를 입력하시오.");
return;
}
frm.submit();
}
}
</script>
</head>
<body>
<table>
<tr>
<td>
[<a href="../index.html">메인으로 돌아가기</a>]
[<a href="boardlist.jsp?page=1">최근 목록 보기</a>] <!-- page=1 고정 -->
[<a href="boardwrite.jsp">새로 글쓰기</a>]
[<a href="#" onclick="window.open('admin.jsp','','width=300,height=150,top=300,left=300')">관리자용</a>]
</td>
</tr>
</table>
<table>
<tr style="background-color: silver;">
<th>번호</th><th>제 목</th><th>작성자</th><th>작성일</th><th>조회</th>
</tr>
<%
request.setCharacterEncoding("utf-8");
try{
spage = Integer.parseInt(request.getParameter("page"));
}catch(Exception e){
spage = 1; //아무것도 안했을 때 (페이지 정보를 넘겨주지 않을 때)는 첫 페이지로..
}
if(spage <= 0 ) spage = 1;
String stype = request.getParameter("stype"); //검색인 경우
String sword = request.getParameter("sword");
//paging
//전체 레코드 수를 알아야 함
boardMgr.totalList();
pageSu = boardMgr.getPageSu();
//out.print("페이지 수:" + pageSu); → 12행 기준 pageSu=3
ArrayList<BoardDTO> list = boardMgr.getDataAll(spage, stype, sword);
for(int i = 0; i < list.size(); i++){
dto = (BoardDTO)list.get(i);
//댓글 들여 쓰기 준비(nested 하나당 공백 4개씩)--------
int nst = dto.getNested();
String tab = "";
//String icon = ""; 으로 이미지로 공백 분간 가능
for(int k = 0; k < nst; k++){
tab += " ";
//icon = "<img src=""...>"
}
%>
<tr>
<td><%=dto.getNum() %></td>
<td>
<%=tab %><a href="boardcontent.jsp?num=<%=dto.getNum()%>&page=<%=spage%>"><%=dto.getTitle() %></a>
<!-- page=: 돌아가기 했을 때 작업하고 있던 현재 페이지로 돌아오기 위해 -->
</td>
<td><%=dto.getName() %></td>
<td><%=dto.getBdate() %></td>
<td><%=dto.getReadcnt() %></td>
</tr>
<%} %>
</table>
<table>
<tr style="text-align: center;"> <!-- 가운데 정렬 -->
<td>
<%
for(int i = 1; i <= pageSu; i++){
if(i == spage){
out.print("<b style='font-size: 12pt; color: red;'>[" + i + "]</b>");
}else{
out.print("<a href=boardlist.jsp?page=" + i + ">[" + i + "]</a>");
}
}
%>
<br><br>
<form action="boardlist.jsp" name="frm" method="post">
<select name="stype">
<option value="title" selected="selected">글 제목</option>
<option value="name">작성자</option>
</select>
<input type="text" name="sword">
<input type="button" value="검색" id="btnSearch">
</form>
</td>
</tr>
</table>
</body>
</html>
[boardwrite.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" type="text/css" href="../css/board.css">
<script>
function check(){
if(frm.name.value==""){
alert("이름을 입력하세요");
frm.name.focus();
}else if(frm.pass.value ==""){
alert("비밀번호를 입력하세요");
frm.pass.focus();
}else if(frm.mail.value ==""){
alert("이메일을 입력하세요");
frm.mail.focus();
}else if(frm.title.value ==""){
alert("제목을 입력하세요");
frm.title.focus();
}else if(frm.cont.value ==""){
alert("내용을 입력하세요");
frm.cont.focus();
}else
frm.submit();
}
</script>
</head>
<body>
<form name="frm" method="post" action="boardsave.jsp">
<table border="1">
<tr>
<td colspan="2"><h2>*** 글쓰기 ***</h2></td>
</tr>
<tr>
<td align="center" width="100">이 름</td>
<td width="430"><input name="name" size="15"></td>
</tr>
<tr>
<td align="center">암 호</td>
<td><input type="password" name="pass" size="15"></td>
</tr>
<tr>
<td align="center">메 일</td>
<td><input name="mail" size="25"></td>
</tr>
<tr>
<td align="center">제 목</td>
<td><input name="title" size="50"></td>
</tr>
<tr>
<td align="center">내 용</td>
<td><textarea name="cont" cols="50" rows="10"></textarea></td>
</tr>
<tr>
<td colspan="2" align="center" height="30">
<input type="button"
value="메 인" onClick="location.href='../index.html'">
<input type="button" value="작 성" onClick="check()">
<input type="button" value="목 록"
onClick="location.href='boardlist.jsp'"></td>
</tr>
</table>
</form>
</body>
</html>
[boardsave.jsp]
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
request.setCharacterEncoding("utf-8");
%>
<jsp:useBean id="boardMgr" class="kr.shop.board.BoardMgr"/>
<jsp:useBean id="bean" class="kr.shop.board.BoardBean"/>
<jsp:setProperty property="*" name="bean" />
<%
bean.setBip(request.getRemoteAddr()); //ip
bean.setBdate(); //overriding 함 //등록일
int maxNum = boardMgr.currentGetNum() + 1;
bean.setNum(maxNum); //글 번호
bean.setGnum(maxNum); //글 그룹 번호
boardMgr.saveData(bean);
response.sendRedirect("boardlist.jsp?page=1"); //저장 후 목록 보기
%>
[boardcontent.jsp]
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<jsp:useBean id="boardMgr" class="kr.shop.board.BoardMgr"></jsp:useBean>
<jsp:useBean id="dto" class="kr.shop.board.BoardDTO"></jsp:useBean>
<%
//http://localhost/web_myshop/board/boardcontent.jsp?num=ㅇ&page=ㅁ
String num = request.getParameter("num"); //int X → String 으로 받음
String spage = request.getParameter("page");
//out.print(num + " " + spage);
boardMgr.updateReadcnt(num); //조회수 증가
dto = boardMgr.getData(num); //상세보기 레코드 얻기
/* 확인용
out.println(dto.getName() + "/");
out.println(dto.getTitle() + "/");
out.println(dto.getCont() + "/");
out.println(dto.getBdate()); */
String name = dto.getName();
String pass = dto.getPass();
String mail = dto.getMail();
String title = dto.getTitle();
String cont = dto.getCont();
String bip = dto.getBip();
String bdate = dto.getBdate();
int cnt = dto.getReadcnt();
String apass = "*****";//관리자 모드 (일반인은 비밀번호를 숨김)
String adminOk = (String)session.getAttribute("adminOk");
if(adminOk != null){
if(adminOk.equalsIgnoreCase("admin")) apass = pass;
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판 상세 보기</title>
<link rel="stylesheet" type="text/css" href="../css/board.css">
</head>
<body>
<table>
<tr>
<td><b>비밀번호: <%=apass %></b></td>
<td colspan="2" style="text-align: right;">
<a href="reply.jsp?num=<%=num %>&page=<%=spage %>">
<img src="../images/reply.gif">
</a>
<a href="edit.jsp?num=<%=num %>&page=<%=spage %>">
<img src="../images/edit.gif">
</a>
<a href="delete.jsp?num=<%=num %>&page=<%=spage %>">
<img src="../images/del.gif">
</a>
<a href="boardlist.jsp?page=<%=spage %>">
<img src="../images/list.gif">
</a>
</td>
</tr>
<tr>
<td>
작성자: <a href="mailto:<%=mail %>"><%=name %> (ip: <%=bip %>)
</td>
<td>작성일: <%=bdate %></td>
<td>조회수: <%=cnt %></td>
</tr>
<tr>
<td colspan="3" style="background-color:cyan">제목: <%=title %></td>
</tr>
<tr>
<td colspan="3">
<textarea rows="10" style="width:99%" readonly="readonly"><%=cont %></textarea>
</td>
</tr>
</table>
</body>
</html>
[reply.jsp]
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<jsp:useBean id="boardMgr" class="kr.shop.board.BoardMgr"/>
<jsp:useBean id="dto" class="kr.shop.board.BoardDTO"/>
<%
String num = request.getParameter("num");
String spage = request.getParameter("page");
dto = boardMgr.getReplyData(num);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>댓글</title>
<link rel="stylesheet" type="text/css" href="../css/board.css">
<script type="text/javascript">
function check(){
if(frm.name.value==""){
alert("이름을 입력하세요");
frm.name.focus();
}else if(frm.pass.value ==""){
alert("비밀번호를 입력하세요");
frm.pass.focus();
}else if(frm.mail.value ==""){
alert("이메일을 입력하세요");
frm.mail.focus();
}else if(frm.title.value ==""){
alert("제목을 입력하세요");
frm.title.focus();
}else if(frm.cont.value ==""){
alert("내용을 입력하세요");
frm.cont.focus();
}else
frm.submit();
}
</script>
</head>
<body>
<form action="replysave.jsp" name="frm" method="post">
<!-- 댓글에 대한 정보를 들고 가야 list 에서 정확한 여백을 주며 보여줄 수 있음 (단, hidden으로 user 눈에는 보이지 않음) -->
<input type="hidden" name="num" value="<%=num %>">
<input type="hidden" name="page" value="<%=spage %>">
<input type="hidden" name="gnum" value="<%=dto.getGnum() %>">
<input type="hidden" name="onum" value="<%=dto.getOnum() %>">
<input type="hidden" name="nested" value="<%=dto.getNested()%>">
<table border="1">
<tr>
<td colspan="2"><h2>*** 댓글쓰기 ***</h2></td>
</tr>
<tr>
<td align="center" width="100">이 름</td>
<td width="430"><input name="name" size="15"></td>
</tr>
<tr>
<td align="center">암 호</td>
<td><input type="password" name="pass" size="15"></td>
</tr>
<tr>
<td align="center">메 일</td>
<td><input name="mail" size="25"></td>
</tr>
<tr>
<td align="center">제 목</td>
<td><input name="title" size="50" value="[RE]:<%=dto.getTitle() %>"></td>
</tr>
<tr>
<td align="center">내 용</td>
<td><textarea name="cont" rows="10" style="width: 100%"></textarea></td>
</tr>
<tr>
<td colspan="2" align="center" height="30">
<input type="button" value="작 성" onClick="check()">
<input type="button" value="목 록"
onClick="location.href='boardlist.jsp?page=<%=spage%>'"></td>
</tr>
</table>
</form>
</body>
</html>
[replysave.jsp]
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
request.setCharacterEncoding("utf-8");
%>
<jsp:useBean id="bean" class="kr.shop.board.BoardBean"/>
<jsp:setProperty property="*" name="bean"/> <%-- 두줄로 setter기능 적용 됨. --%>
<jsp:useBean id="boardMgr" class="kr.shop.board.BoardMgr"/>
<%
String spage = request.getParameter("page"); //boardBean에는 page번호 멤버가 없다
int num = bean.getNum();
int gnum = bean.getGnum();
int onum = bean.getOnum() + 1; //댓글이므로 1증가
int nested = bean.getNested() + 1;//댓글이므로 1증가
//같은 그룹 내에서 새로운 댓글의 onum보다 크거나 같은 값을 댓글 입력 전에 먼저 수정하기. (작으면 수정 안함.)
boardMgr.updateOnum(gnum, onum); //새로운 onum 갱신
//댓글 자료 저장
bean.setOnum(onum);
bean.setNested(nested);
bean.setBip(request.getRemoteAddr());
bean.setBdate(); //overloading으로 argument없이 호출 가능
bean.setNum(boardMgr.currentGetNum() + 1); // 새 댓글의 레코드 번호 값 부여 (가장 큰 값을 가져옴)
boardMgr.saveReplyData(bean);
response.sendRedirect("boardlist.jsp?page=" + spage); //댓글 저장 후 목록 보기
%>
<%-- <!DOCTYPE html> 비즈니스 로직 jsp 파일 이므로 생략--%>
아직 edit, editsave, delete 업로드 안함
▽ 그 외 부수적인 코딩 자료들
WebContent > css > [board.css]
@charset "UTF-8";
table{
width: 80%; margin-left: auto; margin-right: auto;
}
a{
text-decoration: none;
}
body {
margin: 10px;
}
WebContent > WEB-INF > [context.xml]
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc_maria" auth="Container" type="javax.sql.DataSource"
driverClassName="org.mariadb.jdbc.Driver" loginTimeout="10" maxWait="5000"
username="root" password="369369" testOnBorrow="true"
maxActive="500" maxIdle="100"
url="jdbc:mysql://localhost:3306/test" />
</Context>
[admin.jsp]
<%@ 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>
관리자용
</body>
</html>
Q. 왜 저장을 할 때 boardsave, replysave, editsave 라는 파일을 따로 만들까?
A. Business logic
※ 주의
rs = pstmt.executeQuery(); →
pstmt.executeUdate(); →
※페이지 이동
history.back(); → js
response.sendRedirect(); → jsp
'Programming Language > Servlet & JSP' 카테고리의 다른 글
[JSP] (최종 - Model Ⅰ방식) 회원 로그인 및 관리 (feat. session, 팝업창, Openet) (0) | 2020.09.07 |
---|---|
[JSP] *연구* jsp 로 alert창 띄우고 이동시키기 (0) | 2020.09.05 |
[JSP] 로그아웃, 로그인 화면 다르게 하기 (feat. session, include지시어) (0) | 2020.09.02 |
[JSP] beans + dbcp[connection pooling] (0) | 2020.09.02 |
[JSP] (problem) (0) | 2020.08.26 |