BACKEND/아파치 스트럿츠 1 , 2

[struts2] 스트럿츠2 + iBatis를 이용한 답변형 게시판 중 (2) (답변형 게시판 , 수정 , 삭제 )

꾸준히개발하자 2022. 3. 14. 18:01

 

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이다. 

 

1. 게시글 A입력 2. 게시글 B입력

 

게시글 B의 답글 BB1 입력

parent는 부모의 BoardNum 에 해당한다.

B의 답글이므로 parent는 B게시물의 BoardNum = 2 이다. groupNum은 부모의 groupNum을 가져온다.

 

게시글 B의 답글 BB1 입력

게시글 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>

 

게시글 B의 답글 BB2 입력

게시글 A의 답글 AA 입력

A의 답글 이므로 parent A게시물의 BoardNum = 1 이다. 

groupNum은 부모의 groupNum을 가져온다.

 

A의 답글 이므로  parent는 A의 게시물의 BoardNum = 1 이다. 

groupNum은 부모의 groupNum을 가져온다.

 

 

5.게시글 A의 답글 AA 입력

게시글 BB2의 답글 BBB 입력

6번이 게시글이 입력되면 groupNum는 부모의 groupNum을 써주고 depth 부모+1

4번게시물 답변이 작성될때 OrderNo가 동일한 GroupNum(2)을 가지고 OrderNo이 (1) 보다 큰 게시물만 해당된다.

(OrderNo -> 입력된 데이터의 부모 orderNo보다 큰 데이터를 모두 orderNo+1 반영)

 

게시글 BB2의 답글 BBB 입력

 

게시판 URI 정리

 

게시판 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>제&nbsp;&nbsp;&nbsp;&nbsp;목</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>내&nbsp;&nbsp;&nbsp;&nbsp;용</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"/>
				&nbsp;(게시물 수정 및 삭제시 필요!!)
				</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;
	}

 

 

 

list 게시판
Article 게시판
reply 게시판
list 게시판&nbsp;