글쓰기 HTML
글쓰기 페이지의 경우, 답글쓰기 페이지와 똑같은 view를 가지기 때문에, 한 페이지에서 두 가지 기능이 모두 작동하도록 작성한다.
이미 bno가 존재하는지를 통해 답글인지 아닌지 유무를 판단할 수 있다.
<form> 태그를 통해 파라미터를 action으로 전송할 예정이기에,
직접적으로 사용하지 않는 변수들은 hidden으로 설정하여 <form>의 맨 밑 부분에 넣어주었다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글쓰기</title>
<link rel="stylesheet" type="text/css" href="css/form.css">
<script src="jquery/jquery-3.7.0.min.js"></script>
<script type="text/javascript">
$().ready(function(){
$("#submit1").on("click",function(){
if(validate()){
$("form").submit();
}
});
});
function validate(){
let f = $("form[name=writeform] .chk");
let flen = f.length;
for(let i=0;i<flen;i++){
if(f.eq(i).val()==null ||
f.eq(i).val().length==0 ||
f.eq(i).val().trim()==""){
alert(f.eq(i).attr("title")+"의 입력은 필수입니다.");
f.eq(i).focus();
return false;
}
}
return true;
}
</script>
</head>
<body>
<form name="writeform" action="writeAction.do" method="post">
<table>
<tr><td colspan="2"><h3>게시글 쓰기</h3></td></tr>
<tr>
<th>제목</th>
<c:choose>
<c:when test="${dto.bno==0}">
<td><input type="text" name="subject" class="chk" title="제목"></td>
</c:when>
<c:when test="${dto.bno>0}">
<td><input type="text" name="subject" class="chk" title="제목" value="[답글] ${dto.subject}"></td>
</c:when>
</c:choose>
</tr>
<tr>
<th>작성자</th>
<td><input type="text" name="writer" class="chk" title="작성자"></td>
</tr>
<tr>
<th>내용</th>
<td><textarea name="content" class="chk" title="내용"></textarea></td>
</tr>
<tr>
<th>비밀번호</th>
<td><input type="password" name="pw" class="chk" title="비밀번호"></td>
</tr>
<tr>
<td colspan="3">
<input type="button" class="btn" value="글 작성" id="submit1">
<input type="reset" class="btn" value="다시 쓰기">
<input type="button" class="btn" value="글목록" onclick="location.href='list.do'">
</td>
</tr>
</table>
<input type="hidden" name="bno" value="${dto.bno}">
<input type="hidden" name="bref" value="${dto.bref}">
<input type="hidden" name="bstep" value="${dto.bstep}">
<input type="hidden" name="blevel" value="${dto.blevel}">
</form>
</body>
</html>
글쓰기 CSS
@charset "UTF-8";
* {margin:0; padding:0;}
table {
width:80%;
margin: 0 auto;
border:1px solid black;
background-color: #cfcfff;
padding:10px 30px 10px 38px;
}
table th {border : 1px solid balck;}
table tr {text-align:center;}
table th {
text-align:center;
border:1px solid #696969;
background-color: #ffffff;
border-radius: 2px;
}
input {width:90%; padding:3px;}
textarea {
width:90%; height:300px; padding:3px;
resize: none;
}
.btn {
width:100px;
height:30px;
font-weight: bold;
margin-top:15px;
margin-bottom:5px;
background-color: #ffffff;
border:1px solid #696969;
}
h3 {margin:5px 5px 10px 5px;}
글쓰기 JavaScript
<script src="../jquery/jquery-3.7.0.min.js"></script>
<script type="text/javascript">
$().ready(function(){
$("#submit").on("click",function(){
if(validate()){
$("form[name=writeform]").submit();
return true;
} else {return false;}
})
})
function validate(){
let f = $("form[name=writeform] .chk");
let flen = f.length;
for(let i=0;i<flen;i++){
if(f.eq(i).val()==null ||
f.eq(i).val().length==0 ||
f.eq(i).val().trim()==""){
alert(f.eq(i).attr("title")+"의 입력은 필수입니다.");
f.eq(i).focus();
return false;
}
}
return true;
}
</script>
제목, 작성자, 내용, 비밀번호에 chk 클래스를 준다.
클래스의 개수만큼 반복문을 돌리면서 해당 클래스의 value가 비었는지 확인하고, 비었으면 false를 전부 차 있으면 true를 리턴하는 함수를 작성한다.
글작성 버튼에 submit 아이디를 주고, validate() 함수의 return이 true면 form 태그를 submit하도록 한다.
글쓰기 DAO 작성
bno를 key처럼 쓰기 위해 서로 겹치지 않도록,
전체 bno를 조회하고 그 중 MAX 값보다 1이 더 크도록 설정했다.
또한, DAO에서도 답글일 경우를 분류해
답글인 경우 bstep, blevel이 높아지도록 설정했다.
public int writeArticle(BoardDTO dto){
int result = 0;
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
int newBno = 0;
try {
conn = DBConnector.getInstance().getConnection();
String sql = "SELECT IFNULL(MAX(bno),0)+1 AS bno FROM board";
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
if(rs.next())
newBno = rs.getInt(1);
pstmt.close();
sql = "INSERT INTO board"
+ "(bno, bref, bstep, blevel, readcount, subject, "
+ "content, writer, passwd, ip, regdate) "
+ "VALUE(?,?,?,?,?,?,?,?,?,?,SYSDATE())";
pstmt = conn.prepareStatement(sql);
if(dto.getBno() > 0) {
dto.setBno(newBno);
dto.setBstep(dto.getBstep()+1);
dto.setBlevel(dto.getBlevel()+1);
} else {
dto.setBno(newBno);
dto.setBref(newBno);
dto.setBstep(newBno);
}
pstmt.setInt(1, dto.getBno());
pstmt.setInt(2, dto.getBref());
pstmt.setInt(3, dto.getBstep());
pstmt.setInt(4, dto.getBlevel());
pstmt.setInt(5, dto.getReadcount());
pstmt.setString(6, dto.getSubject());
pstmt.setString(7, dto.getContent());
pstmt.setString(8, dto.getWriter());
pstmt.setString(9, dto.getPasswd());
pstmt.setString(10, dto.getIp());
result = pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(conn!=null) conn.close();
if(pstmt!=null) pstmt.close();
} catch(SQLException e) {
e.printStackTrace();
}
}
return result;
}
글쓰기 jsp 불러오는 Action 작성
글쓰기 jsp 파일에도 파라미터를 전달해주어야하기 때문에, 글쓰기 버튼을 눌러도 컨트롤러가 글쓰기 폼으로 가는 action을 먼저 부르도록 해야한다.
bno를 통해 답글인지 아닌지 확인 후, 답글일 경우 파라미터를 전송해서 제대로 답글 기능을 할 수 있도록 설정했다.
package action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import model.BoardDTO;
public class WriteFormAction implements CommandAction {
@Override
public String requestProc(HttpServletRequest request, HttpServletResponse response) throws Exception {
if(request.getParameter("bno")!=null) {
BoardDTO dto = new BoardDTO();
dto.setBno(Integer.parseInt(request.getParameter("bno")));
dto.setBref(Integer.parseInt(request.getParameter("bref")));
dto.setBstep(Integer.parseInt(request.getParameter("bstep")));
dto.setBlevel(Integer.parseInt(request.getParameter("blevel")));
dto.setSubject(request.getParameter("subject"));
request.setAttribute("dto", dto);
}
return "view/WriteForm.jsp";
}
}
글쓰기 수행하는 Action
답글일 경우 기존의 bno, bref, bstep, blevel을 가져오고,
새글일 경우 subject, writer, content, pw만 가져오도록 한다.
DAO에 만든 글작성 메소드를 실행 후, 실행 결과의 성공 여부를 정수형 변수 r에 받는다.
r이 0보다 클 경우 작성 성공, 아닌 경우 작성 실패 메시지를
MsgPage.jsp 문서에 전송한다.
package action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import model.BoardDAO;
import model.BoardDTO;
public class WirteAction implements CommandAction {
@Override
public String requestProc(HttpServletRequest request, HttpServletResponse response) throws Exception {
BoardDTO dto = new BoardDTO();
dto.setSubject(request.getParameter("subject"));
dto.setWriter(request.getParameter("writer"));
dto.setContent(request.getParameter("content"));
dto.setPasswd(request.getParameter("pw"));
dto.setIp(request.getRemoteAddr());
if(request.getParameter("bno") != null && request.getParameter("bno").length()!=0) {
dto.setBno(Integer.parseInt(request.getParameter("bno")));
dto.setBref(Integer.parseInt(request.getParameter("bref")));
dto.setBstep(Integer.parseInt(request.getParameter("bstep")));
dto.setBlevel(Integer.parseInt(request.getParameter("blevel")));
}
BoardDAO dao = BoardDAO.getInstance();
int r = dao.writeArticle(dto);
String msg = "";
String page = "list.do";
if(r>0) msg = "작성 성공";
else msg = "작성 실패";
request.setAttribute("msg", msg);
request.setAttribute("page", page);
return "view/MsgPage.jsp";
}
}
controller 이동 매핑 작성
<!-- Command.properties 파일 -->
/list.do=action.ListAction
/writeForm.do=action.WriteFormAction
/wirteAction.do=action.WriteAction