11일에 진행된 스트럿츠2 + iBatis를 이용한 답변형 게시판 을 하면서
게시판 리스트출력 게시물 클릭 일련번호를 했었다.
오늘은 답변형게시판의 하이라이트인 답변 , 수정 , 삭제 를 하였다.
테이블 구조
2. 답글 정렬 알고리즘
1,5 동일 그룹 1번 / 2,3,4 동일 그룹 2번
groupNum은 최상위 parent BoardNum을 의미한다
depth 답변의 심도를 의미한다. parent에 해당하는 레코드의 depth + 1 값을 반영한다.
orderNo은 같은 그룹 안에서 출력되는 순서를 의미한다.(desc-내림차순정렬)
항상 나중에 입력된 게시글이 위로 올라간다.
parent가 없는 게시물의 경우 depth , orderNo, parent 모두 0으로 입력되고 ,groupNum도 자기자신의 BoardNum이다.
게시글 B의 답글 BB1 입력
parent는 부모의 BoardNum 에 해당한다.
B의 답글이므로 parent는 B게시물의 BoardNum = 2 이다. groupNum은 부모의 groupNum을 가져온다.
게시글 B의 답글 BB2 입력
4번 게시글이 3번 게시글 이후로 작성되어서 위에 반영된 것이다.
4번 게시글의 (orderNo은 parent의 orderNo+1로 '1'이 입력)이 되고 ,
3번 게시글의 OrderNo은 기존 값에서 +1 하여 '2' 로 변경된다.
답변 게시물이 입력되는 경우 OrderNo가 변경되는 기준은 동일한 GroupNum을 가지고 OrderNo이 입력되는 값보다
큰 게시물만 해당된다.
<!-- 답변일 경우 orderNo를 변경 -->
<update id="orderNoUpdate" parameterClass="map">
update bbs set orderNo=orderNo+1
where groupNum=#groupNum# and orderNo>#orderNo#
</update>
게시글 A의 답글 AA 입력
A의 답글 이므로 parent A게시물의 BoardNum = 1 이다.
groupNum은 부모의 groupNum을 가져온다.
A의 답글 이므로 parent는 A의 게시물의 BoardNum = 1 이다.
groupNum은 부모의 groupNum을 가져온다.
게시글 BB2의 답글 BBB 입력
6번이 게시글이 입력되면 groupNum는 부모의 groupNum을 써주고 depth 부모+1
4번게시물 답변이 작성될때 OrderNo가 동일한 GroupNum(2)을 가지고 OrderNo이 (1) 보다 큰 게시물만 해당된다.
(OrderNo -> 입력된 데이터의 부모 orderNo보다 큰 데이터를 모두 orderNo+1 반영)
게시판 URI 정리
게시글 조회 기능
1. board_sqlMap.xml 작성 (iBatis)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap
PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="bbs">
<!-- 별칭을줘서 간단하게 쓸수있다. -->
<typeAlias alias="boardDTO" type="com.board.BoardDTO"/>
<select id="maxBoardNum" resultClass="int">
select nvl(max(boardNum),0) from bbs
</select>
<insert id="insertData" parameterClass="boardDTO">
insert into bbs (boardNum,name,pwd,email,subject,content,
ipAddr,groupNum,depth,orderNo,parent,hitCount,created) values
(#boardNum#,#name#,#pwd#,#email#,#subject#,#content#,
#ipAddr#,#groupNum#,#depth#,#orderNo#,#parent#,0,sysdate)
</insert>
<select id="dataCount" resultClass="int" parameterClass="map">
select nvl(count(*),0) from bbs
where $searchKey$ like '%' || #searchValue# || '%'
</select>
<!-- 그룹은 큰순서로 정렬 , orderNo 작은순서로 정렬 -->
<select id="listData" resultClass="boardDTO" parameterClass="map">
select * from (
select rownum rnum, data.* from (
select boardNum,name,subject,depth,hitCount,
to_char(created,'YYYY-MM-DD') created from bbs
where $searchKey$ like '%' || #searchValue# || '%'
order by groupNum desc,orderNo asc) data)
<![CDATA[
where rnum>=#start# and rnum<=#end#
]]>
</select>
<!-- Article -->
<!-- 조회수 증가 -->
<update id="hitCountUpdate" parameterClass="int">
update bbs set hitCount=hitCount+1 where boardNum=#boardNum#
</update>
<!-- 하나의 데이터 가져옴 -->
<select id="readData" parameterClass="int" resultClass="boardDTO">
select boardNum,name,pwd,email,subject,content,ipAddr,
groupNum,depth,orderNo,parent,hitCount,created
from bbs where boardNum=#boardNum#
</select>
<!-- 이전글 다음글 -->
<!-- 그룹넘버가 같으면서 orderNo가 현재보다 작아야한다. -->
<!-- 이전글이 최신글이다. -->
<select id="preReadData" parameterClass="map" resultClass="boardDTO">
select data.* from (
select boardNum,subject from bbs
where ($searchKey$ like '%' || #searchValue# || '%')
<![CDATA[
and ((groupNum=#groupNum# and orderNo<#orderNo#)
or(groupNum>#groupNum#))
order by groupNum asc,orderNo desc) data
where rownum=1
]]>
</select>
<!-- 다음글이 예전에 쓴글 -->
<select id="nextReadData" parameterClass="map" resultClass="boardDTO">
select data.* from (
select boardNum,subject from bbs
where ($searchKey$ like '%' || #searchValue# || '%')
<![CDATA[
and ((groupNum=#groupNum# and orderNo>#orderNo#)
or(groupNum<#groupNum#))
order by groupNum desc,orderNo asc) data
where rownum=1
]]>
</select>
<!-- orderNo를 수정하는 쿼리 , groupNum은 같아야한다. 사용자보다 큰 orderNo 1씩증가 -->
<update id ="orderNoUpdate" parameterClass="map">
update bbs set orderNo = orderNo + 1
where groupNum = #groupNum# and orderNo>#orderNo#
</update>
<!-- 우리의 데이터를 수정하는 쿼리 -->
<update id="updateData" parameterClass="boardDTO">
update bbs set name=#name#,subject=#subject#,email=#email#,
content=#content#,pwd=#pwd# where boardNum=#boardNum#
</update>
<delete id="deleteData" parameterClass="int">
delete bbs
where boardNum in (select boardNum from bbs start with boardNum=#boardNum#
connect by prior boardNum=parent)
</delete>
</sqlMap>
이전글 - groupNum 오름차순 orderNo 내림차순
최신글로서 상단에 온다. groupNum이 같으면 orderNo이 작고
groupNum이 다르면 나보다 groupNum이 크다
다음글 - groupNum 내림차순 orderNo 오름차순
오래전에 쓴 글로써 하단에 오는데 groupNum이 같으면 orderNo이 나보다 크고
groupNum이 다르면 나보다 groupNum이 작다
orderNoUpdate 쿼리 - groupNum이 같으면 orderNo 1씩 증가시킨다.
updateData - 데이터를 수정한다.
deleteData - boardNum이 삭제되면 의 부모의 boardNum도 연결도 삭제된다.
2. struts-board.xml 액션 등록 (struts2) - Controller 역할
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts
PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<!-- Controller 역할 -->
<!-- extends 의 default 는 packagename 의 default struts.xml과 연결되게끔함 -->
<!-- 주소창을 여기서 친다 -->
<struts>
<package name="board" extends="default" namespace="/bbs">
<!-- /bbs에 created.Action 이 오면 BoardAction 으로 가서 created메소드를 실행해라 -->
<action name="created" class="com.board.BoardAction" method="created">
<result name="input">/board/created.jsp</result>
<!-- 입력이 됬으므로 리다이랙트(수정,세션된건) -->
<result name="success" type="redirectAction">list</result>
</action>
<action name="list" class="com.board.BoardAction" method="list">
<result name="success">/board/list.jsp</result>
</action>
<action name="article" class="com.board.BoardAction" method="article">
<result name="success">/board/article.jsp</result>
</action>
</package>
</struts>
3. Action 클래스의 article 메소드 생성 (Model)
// 클릭해서 dto는 자동으로 넘어온다.
public String article() throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
CommonDAO dao = CommonDAOImpl.getInstance();
// 스트럿츠2가 자동으로 dto를 넘겨줘서 pageNum과 boardNum이 나오게 된다.
/*System.out.print(dto.getSearchKey());
System.out.print(dto.getSearchValue());
System.out.print(dto.getPageNum());
System.out.print(dto.getBoardNum());*/
// dao에서 하나의 데이터를 가져올것이다.
// 넘어오는값을 변수에 빼놓는다.
String searchKey = dto.getSearchKey();
String searchValue = dto.getSearchValue();
String pageNum = dto.getPageNum();
int boardNum = dto.getBoardNum();
if(searchValue==null||searchValue.equals("")) {
searchKey = "subject";
searchValue = "";
}
if(request.getMethod().equalsIgnoreCase("GET")) {
searchValue = URLDecoder.decode(searchValue, "UTF-8");
}
// 조회수 증가
dao.updateData("bbs.hitCountUpdate", boardNum);
// 하나의 데이터를 읽어와서 dto에 넣어준다.
dto = (BoardDTO)dao.getReadData("bbs.readData",boardNum);
// nullnullnull3 검색을 했는데도 key,value,pagenum 없어짐..
// 위에는 있어서 출력이 됐는데
// 진행하다 보니까 자동으로 넘어온 dto가 이 밑에서
// getReadData에 의해서 기존에 있는게 덮어져서 초기화됨
// 맨 마지막에 boardNum만 보이게 된다.
// 우리가 별도로 자동으로 넘어온 dto를 빼놔서
// 아래에서 사용을 하게되는것이다.
/*System.out.print(dto.getSearchKey());
System.out.print(dto.getSearchValue());
System.out.print(dto.getPageNum());
System.out.print(dto.getBoardNum());*/
if(dto==null) {
return "read-error";
}
// dto에서 꺼냈으니 content는 있으나 키벨류페이지넘은 초기화되어있음..
int lineSu = dto.getContent().split("\r\n").length;
dto.setContent(dto.getContent().replaceAll("\r\n", "<br/>"));
// 이전글 다음글보낼것임
Map<String, Object> hMap = new HashMap<>();
// hMap.put("searchKey", dto.getSearchKey()); 이렇게 넣어주면안됨 위에 자동으로 넣은 dto sk,sv,pn 이 초기화 되어있어서
// 널이 들어가면 검색이 안된다..
hMap.put("searchKey", searchKey); // 그럼 여기다가 위에서 dto.getSearchKey 로
// 받은 searchKey변수 를 써줘야 한다.
hMap.put("searchValue", searchValue);
hMap.put("groupNum", dto.getGroupNum());
hMap.put("orderNo", dto.getOrderNo());
// 이전글
BoardDTO preDTO = (BoardDTO)dao.getReadData("bbs.preReadData",hMap);
int preBoardNum = 0;
String preSubject = "";
if(preDTO!=null) {
preBoardNum = preDTO.getBoardNum();
preSubject = preDTO.getSubject();
}
BoardDTO nextDTO = (BoardDTO)dao.getReadData("bbs.nextReadData",hMap);
int nextBoardNum = 0;
String nextSubject = "";
if(nextDTO!=null) {
nextBoardNum = nextDTO.getBoardNum();
nextSubject = nextDTO.getSubject();
}
// 넘어가는 주소
String params = "pageNum=" + pageNum;
if(!searchValue.equals("")) {
params += "&searchKey=" + searchKey;
params += "&searchValue="
+ URLEncoder.encode(searchValue,"UTF-8");
}
request.setAttribute("preBoardNum", preBoardNum);
request.setAttribute("preSubject",preSubject);
request.setAttribute("nextBoardNum", nextBoardNum);
request.setAttribute("nextSubject",nextSubject);
request.setAttribute("params",params);
request.setAttribute("lineSu",lineSu);
request.setAttribute("pageNum",pageNum);
// 이제 sql에 이전글 다음글로 넘어가게 된다.
return SUCCESS;
}
4. Article.jsp 생성 (View)
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
request.setCharacterEncoding("UTF-8");
String cp = request.getContextPath();
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>게 시 판</title>
<link rel="stylesheet" type="text/css" href="<%=cp%>/board/css/style.css"/>
<link rel="stylesheet" type="text/css" href="<%=cp%>/board/css/article.css"/>
<script type="text/javascript">
/* article의 dto가 자동으로 넘어온다. 넘어오는 dto를 받는다 */
function sendData(value) {
/* 넘어오는 dto를 스크립트에서 변수로 받을수있다. */
var boardNum = "${dto.boardNum}";
var pageNum = "${pageNum}";
var url = "<%=cp%>/bbs/";
if(value=="delete") {
url += "deleted.action";
} else if(value=="update") {
url += "updated.action";
} else if(value=="reply") {
url += "reply.action"
}
/* params는 serachkey,searchvalue,pageNum이 넘어온다. */
url += "?boardNum=" + boardNum;
url += "&${params}";
// 이동
location.replace(url);
}
</script>
</head>
<body>
<div id="bbs">
<div id="bbs_title">
게 시 판 (Struts2)
</div>
<div id="bbsArticle">
<div id="bbsArticle_header">
${dto.subject }
</div>
<div class="bbsArticle_bottomLine">
<dl>
<dt>작성자</dt>
<dd>${dto.name }</dd>
<dt>줄수</dt>
<dd>${lineSu }</dd>
</dl>
</div>
<div class="bbsArticle_bottomLine">
<dl>
<dt>등록일</dt>
<dd>${dto.created }</dd>
<dt>조회수</dt>
<dd>${dto.hitCount }</dd>
</dl>
</div>
<div id="bbsArticle_content">
<table width="600" border="0">
<tr>
<td style="padding-left: 20px 80px 20px 62px;"
valign="top" height="200">
${dto.content }
</td>
</tr>
</table>
</div>
<div class="bbsArticle_bottomLine">
이전글:
<!-- 제목이 있을때만 보여준다. -->
<c:if test="${!empty preSubject }">
<a href="<%=cp %>/bbs/article.action?${params }&boardNum=${preBoardNum }">
${preSubject }</a>
</c:if>
</div>
<div class="bbsArticle_noLine">
다음글:
<!-- 제목이 있을때만 보여준다. -->
<c:if test="${!empty nextSubject }">
<a href="<%=cp%>/bbs/article.action?${params}&boardNum=${nextBoardNum}">
${nextSubject }</a>
</c:if>
</div>
</div>
<div class="bbsArticle_noLine" style="text-align: right">
From : ${dto.ipAddr }
</div>
<div id="bbsArticle_footer">
<div id="leftFooter">
<input type="button" value=" 답변 " class="btn2" onclick="sendData('reply')"/>
<input type="button" value=" 수정 " class="btn2" onclick="sendData('update')"/>
<input type="button" value=" 삭제 " class="btn2" onclick="sendData('delete')"/>
</div>
<div id="rightFooter">
<input type="button" value=" 리스트 " class="btn2"
onclick="javascript:location.href='<%=cp%>/bbs/list.action?${params }'"/>
</div>
</div>
</div>
</body>
</html>
게시글 수정/답변기능 (답변 : insert/수정 : update)
1. board_sqlMap.xml SQL문 작성
<!-- orderNo를 수정하는 쿼리 , groupNum은 같아야한다. 사용자보다 큰 orderNo 1씩증가 -->
<update id ="orderNoUpdate" parameterClass="map">
update bbs set orderNo = orderNo + 1
where groupNum = #groupNum# and orderNo>#orderNo#
</update>
<!-- 우리의 데이터를 수정하는 쿼리 -->
<update id="updateData" parameterClass="boardDTO">
update bbs set name=#name#,subject=#subject#,email=#email#,
content=#content#,pwd=#pwd# where boardNum=#boardNum#
</update>
2.struts-board.xml 매핑정보 작성
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts
PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<!-- Controller 역할 -->
<!-- extends 의 default 는 packagename 의 default struts.xml과 연결되게끔함 -->
<!-- 주소창을 여기서 친다 -->
<struts>
<package name="board" extends="default" namespace="/bbs">
<!-- /bbs에 created.Action 이 오면 BoardAction 으로 가서 created메소드를 실행해라 -->
<action name="created" class="com.board.BoardAction" method="created">
<result name="input">/board/created.jsp</result>
<!-- 입력이 됬으므로 리다이랙트(수정,세션된건) -->
<result name="success" type="redirectAction">list</result>
</action>
<action name="list" class="com.board.BoardAction" method="list">
<result name="success">/board/list.jsp</result>
</action>
<action name="article" class="com.board.BoardAction" method="article">
<result name="success">/board/article.jsp</result>
</action>
<!-- struts2 에서는 list뒤에 get방식으로 데이터를 넘길수있다. -->
<action name="updated" class="com.board.BoardAction" method="updated">
<result name="input">/board/created.jsp</result>
<result name="success" type="redirectAction">list?pageNum=${dto.pageNum}</result>
</action>
<action name="reply" class="com.board.BoardAction" method="reply">
<result name="input">/board/created.jsp</result>
<result name="success" type="redirectAction">list?pageNum=${dto.pageNum}</result>
</action>
<action name="deleted" class="com.board.BoardAction" method="deleted">
<result name="success" type="redirectAction">list?pageNum=${dto.pageNum}</result>
</action>
</package>
</struts>
3. created.jsp 수정 (Mode에 따른 버튼 변경 및 호출 액션 설정)
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
request.setCharacterEncoding("UTF-8");
String cp = request.getContextPath();
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>게 시 판</title>
<link rel="stylesheet" type="text/css" href="<%=cp%>/board/css/style.css"/>
<link rel="stylesheet" type="text/css" href="<%=cp%>/board/css/created.css"/>
<script type="text/javascript" src="<%=cp%>/board/js/util.js"></script>
<script type="text/javascript">
function sendIt(){
var f = document.myForm;
str = f.subject.value;
str = str.trim();
if(!str){
alert("\n제목을 입력하세요.");
f.subject.focus();
return;
}
f.subject.value = str;
str = f.name.value;
str = str.trim();
if(!str){
alert("\n이름을 입력하세요.");
f.name.focus();
return;
}
/* if(!isValidKorean(str)){
alert("\n이름을 정확히 입력하세요.");
f.name.focus()
return;
} */
f.name.value = str;
if(f.email.value){
if(!isValidEmail(f.email.value)){
alert("\n정상적인 E-Mail을 입력하세요.");
f.email.focus();
return;
}
}
str = f.content.value;
str = str.trim();
if(!str){
alert("\n내용을 입력하세요.");
f.content.focus();
return;
}
f.content.value = str;
str = f.pwd.value;
str = str.trim();
if(!str){
alert("\n패스워드를 입력하세요.");
f.pwd.focus();
return;
}
f.pwd.value = str;
/* 입력 수정 댓글 */
/* request.setAttribute("mode", "create"); */
/* 주소를 분리해놨다. */
if(f.mode.value=="create") {
f.action = "<%=cp%>/bbs/created.action";
}else if(f.mode.value=="update") {
f.action = "<%=cp%>/bbs/updated.action";
}else if(f.mode.value=="reply") {
f.action = "<%=cp%>/bbs/reply.action";
}
f.submit();
}
</script>
</head>
<body>
<div id="bbs">
<div id="bbs_title">
게 시 판 (Struts2)
</div>
<form action="" method="post" name="myForm">
<div id="bbsCreated">
<div class="bbsCreated_bottomLine">
<dl>
<dt>제 목</dt>
<dd>
<input type="text" name="subject" value="${dto.subject }" size="60"
maxlength="100" class="boxTF"/>
</dd>
</dl>
</div>
<div class="bbsCreated_bottomLine">
<dl>
<dt>작성자</dt>
<dd>
<input type="text" name="name" value="${dto.name }" size="35"
maxlength="20" class="boxTF"/>
</dd>
</dl>
</div>
<div class="bbsCreated_bottomLine">
<dl>
<dt>E-Mail</dt>
<dd>
<input type="text" name="email" value="${dto.email }" size="35"
maxlength="50" class="boxTF"/>
</dd>
</dl>
</div>
<div id="bbsCreated_content">
<dl>
<dt>내 용</dt>
<dd>
<textarea rows="12" cols="63" name="content"
class="boxTA">${dto.content }</textarea>
</dd>
</dl>
</div>
<div class="bbsCreated_noLine">
<dl>
<dt>패스워드</dt>
<dd>
<input type="password" name="pwd" value="${dto.pwd }" size="35"
maxlength="7" class="boxTF"/>
(게시물 수정 및 삭제시 필요!!)
</dd>
</dl>
</div>
</div>
<div id="bbsCreated_footer">
<!-- 수정으로 쓸곳 , 수정하기 위해서 필요한것이다. -->
<input type="hidden" name="boardNum" value="${dto.boardNum }"/>
<!-- 변수에 담아서 보내주무르 dto.pageNum에서 pageNum으로 바꾼다.
req.setAttribute( -->
<input type="hidden" name="pageNum" value="${pageNum }"/>
<!-- 댓글달때 필요하므로 써놓음 -->
<input type="hidden" name="groupNum" value="${dto.groupNum }"/>
<input type="hidden" name="orderNo" value="${dto.orderNo }"/>
<input type="hidden" name="depth" value="${dto.depth }"/>
<!-- parent에는 부모의 boardNum이 들어간다. -->
<input type="hidden" name="parent" value="${dto.boardNum }"/>
<!-- 입력용인지 수정용인지 댓글용인지 -->
<input type="hidden" name="mode" value="${mode }"/>
<c:if test="${mode=='create' }">
<input type="button" value=" 등록하기 " class="btn2" onclick="sendIt();"/>
<input type="reset" value=" 다시입력 " class="btn2"
onclick="document.myForm.subject.focus();"/>
<!-- 넘어갈때 pageNum도 넘어갈수있게 한다. -->
<input type="button" value=" 작성취소 " class="btn2"
onclick="javascript:location.href='<%=cp%>/bbs/list.action?pageNum=${pageNum }';"/>
</c:if>
<c:if test="${mode=='update' }">
<input type="button" value=" 수정하기 " class="btn2" onclick="sendIt();"/>
<!-- 넘어갈때 pageNum도 넘어갈수있게 한다. -->
<input type="button" value=" 수정취소 " class="btn2"
onclick="javascript:location.href='<%=cp%>/bbs/list.action?pageNum=${pageNum }';"/>
</c:if>
<c:if test="${mode=='reply' }">
<input type="button" value=" 답변등록하기 " class="btn2" onclick="sendIt();"/>
<input type="reset" value=" 다시입력 " class="btn2"
onclick="document.myForm.subject.focus();"/>
<!-- 넘어갈때 pageNum도 넘어갈수있게 한다. -->
<input type="button" value=" 작성취소 " class="btn2"
onclick="javascript:location.href='<%=cp%>/bbs/list.action?pageNum=${pageNum }';"/>
</c:if>
</div>
</form>
</div>
</body>
</html>
4. Action class updated 메소드 작성
public String updated() throws Exception {
// 게시물 수정 화면
HttpServletRequest request = ServletActionContext.getRequest();
CommonDAO dao = CommonDAOImpl.getInstance();
if(dto.getMode()==null||dto.getMode().equals("")) {
dto = (BoardDTO)dao.getReadData("bbs.readData",dto.getBoardNum()); // 하나의 데이터 읽어옴
if(dto==null) {
return "read-error";
}
request.setAttribute("mode", "update");
request.setAttribute("pageNum", dto.getPageNum());
return INPUT;
}
// 게시물 수정
// DTO는 자동으로 넘어감
dao.updateData("bbs.updateData", dto);
return SUCCESS;
}
5. action클래스 reply 메소드 생성
// 답변
public String reply() throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
CommonDAO dao = CommonDAOImpl.getInstance();
if(dao==null||dto.getMode()==null||dto.getMode().equals("")) {
// 부모의 데이터 읽기
dto = (BoardDTO)dao.getReadData("bbs.readData",dto.getBoardNum());
if(dto==null) {
return "read-error";
}
// 부모의 컨텐츠를 먼저 보여주고 줄을 귿고 내가 쓰고싶은글을쓴다
String temp = "\r\n\r\n-----------------------------\r\n\r\n";
temp += "[답변]\r\n";
//부모데이터를 변경해서 내 데이터로 created.jsp에 출력
dto.setSubject("[답변]" + dto.getSubject()); // 부모꺼로 바꿈
dto.setContent(dto.getContent() + temp); // 위에 만든 temp를 붙임
dto.setName(""); // name은 내꺼쓸수있게 부모꺼 지울거임
dto.setEmail(""); // 내꺼쓸수있게 부모꺼 지울거임
dto.setPwd(""); // 내꺼쓸수있게 부모꺼 지울거임
request.setAttribute("mode", "reply");
request.setAttribute("pageNum", dto.getPageNum());
return INPUT;
}
// 답변입력 하기전에 orderNum 수정
// ordeNoUpdate 를 넘겨줘야 한다. orderNo 1 증가시켜줘야함
Map<String, Object> hMap = new HashMap<>();
// 위에서 부모의 dto가 자동으로 넘어온다.
hMap.put("groupNum", dto.getGroupNum()); // 부모의 groupNum
hMap.put("orderNo", dto.getOrderNo()); // 부모의 orderNo
dao.updateData("bbs.orderNoUpdate", hMap); // 부모껄 넘기면 orderNo 를 +1 해줌
// 입력
int maxBoardNum = dao.getIntValue("bbs.maxBoardNum");
dto.setBoardNum(maxBoardNum + 1);
dto.setIpAddr(request.getRemoteAddr()); // 새로운 댓글을 다는 사람의 ip를 넣는다 클라이언트 ip를 넣는다.
dto.setDepth(dto.getDepth() + 1); // 부모가 가지고 있는 depth 에 + 1해야지 들여쓰기됨
dto.setOrderNo(dto.getOrderNo() + 1); // 입력된 데이터에 내 부모의 orderNo에 + 1해줌 ( 현재 입력되는 데이터의 orderNo )
// 실제 데이터에 입력
dao.insertData("bbs.insertData", dto);
return SUCCESS;
}
게시물 삭제
2. struts-board.xml 에 deleted는 redirect 정보 등록
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts
PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<!-- Controller 역할 -->
<!-- extends 의 default 는 packagename 의 default struts.xml과 연결되게끔함 -->
<!-- 주소창을 여기서 친다 -->
<struts>
<package name="board" extends="default" namespace="/bbs">
<!-- /bbs에 created.Action 이 오면 BoardAction 으로 가서 created메소드를 실행해라 -->
<action name="created" class="com.board.BoardAction" method="created">
<result name="input">/board/created.jsp</result>
<!-- 입력이 됬으므로 리다이랙트(수정,세션된건) -->
<result name="success" type="redirectAction">list</result>
</action>
<action name="list" class="com.board.BoardAction" method="list">
<result name="success">/board/list.jsp</result>
</action>
<action name="article" class="com.board.BoardAction" method="article">
<result name="success">/board/article.jsp</result>
</action>
<!-- struts2 에서는 list뒤에 get방식으로 데이터를 넘길수있다. -->
<action name="updated" class="com.board.BoardAction" method="updated">
<result name="input">/board/created.jsp</result>
<result name="success" type="redirectAction">list?pageNum=${dto.pageNum}</result>
</action>
<action name="reply" class="com.board.BoardAction" method="reply">
<result name="input">/board/created.jsp</result>
<result name="success" type="redirectAction">list?pageNum=${dto.pageNum}</result>
</action>
<action name="deleted" class="com.board.BoardAction" method="deleted">
<result name="success" type="redirectAction">list?pageNum=${dto.pageNum}</result>
</action>
</package>
</struts>
3. BoardAction deleted 메소드 생성
public String deleted() throws Exception {
CommonDAO dao = CommonDAOImpl.getInstance();
dao.deleteData("bbs.deleteData", dto.getBoardNum());
return SUCCESS;
}
'BACKEND > 아파치 스트럿츠 1 , 2' 카테고리의 다른 글
[Struts2] 스트럿츠2 + iBatis 파일업로드/다운로드/보기 기능 (0) | 2022.03.14 |
---|---|
[Struts1] 스트럿츠1 + iBatis 파일업로드 (2) | 2022.03.14 |
[struts2] 스트럿츠2 + iBatis를 이용한 답변형 게시판 중 1 (글쓰기 , 수정 , 이전글 , 다음글 ) (0) | 2022.03.14 |
[struts1] 스트럿츠1 + iBatis 게시판 만들기 (0) | 2022.03.07 |