JSP

부트캠프54일 (답변게시판 , 수정 , 삭제 , 권한)

동곤일상 2025. 4. 18. 17:46
반응형

 

1)list 날짜format

2)답변게시판(replyForm)

3)수정(updateForm)

4)삭제(deleteForm)

5)list수정(접근권한관련)

6) Book ( 주말에할거임)

 

 

 

 


1) list부분 날짜 표시 변경

기존의 날짜 표현방

 

<td>{b.regdate}</td>


위의 방식에서 밑에 코드로 변경했음!!(fmt태그를 사용한 format)

(type="both"를 쓰거나 pattern을 사용한다)  

또한 오늘날짜에 등록한 데이터는 시간만표시한다

//Controller에서 오늘날짜로 속성을 만들어 넘길거임
request.setAttribute("today", new Date()); //오늘날짜
		 <td>
		 <fmt:formatDate value="${b.regdate}" type="date" var="rdate"/>
		 <fmt:formatDate value="${today}" type="date" var="tdate"/> 
         <!--var 지정시 출력이되지않음(속성만 만들어짐) --->
		 <c:if test="${rdate==tdate}">
		 	<fmt:formatDate value="${b.regdate}" type="time"/>
		 </c:if>
		 <c:if test="${rdate!=tdate}">
		 	<fmt:formatDate value="${b.regdate}" type="both"/>
		 </c:if>
		</td>

 

 

2) 답변 게시판

num grp grplevel grpstep

 

replyForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- 답변글은 num을 파라미터로받음(답변을 달 글의 num) -->
<title>답변 게시글</title>
</head>
<body>
<form action="reply" method="post" name="f">
<input type="hidden" name="num" value="${b.num}">
<input type="hidden" name="grp" value="${b.grp}">
<input type="hidden" name="grplevel" value="${b.grplevel}">
<input type="hidden" name="grpstep" value="${b.grpstep}">
<input type="hidden" name="boardid" value="${b.boardid}">
<div class="container">
<h2>${(b.boardid eq '1')?"공지사항":"자유게시판"}</h2>
<table class="table">
<tr><th>글쓴이</th>
	<td><input type="text" name="writer" class="form-control"></td></tr>
<tr><th>비밀번호</th>
	<td><input type="password" name="pass" class="form-control"></td></tr>
<tr><th>제목</th>
	<td><input type="text" name="title" class="form-control" value="RE:${b.title}"></td></tr>
<tr><th>내용</th>
<td><textarea rows="15" name="content" class="form-control" id="content"></textarea>
<tr><td colspan="2" align="center">
	<a href="javascript:document.f.submit()">[답변글등록]</a></td></tr>
</table>
</div>
</form>

</body>
</html>

 

replyForm과 reply 매핑부분 (Controller) 

noticeCheck함수(관리자만접근할수있게설정하는부분)

	public String noticeCheck(HttpServletRequest request , 
			HttpServletResponse response) { //관리자만 접근할수있게
		String login = (String)request.getSession().getAttribute("login");
		String boardid = (String)request.getSession().getAttribute("boardid");

		if(!login.equals("admin")) {
			request.setAttribute("msg", "관리자만 글쓸수있어요");
			request.setAttribute("url",
					request.getContextPath()+"/board/list?boardid="+boardid);
			return "alert";
		}
		return null;	
	}

	@RequestMapping("writeForm") 
	@MSLogin("noticeCheck") 	//writeForm에 접속 시 실행됨
	public String writeForm(HttpServletRequest request , 
			HttpServletResponse response) {
		return "board/writeForm";
	}
	
	@MSLogin("noticeCheck")
	@RequestMapping("write")
	public String write(HttpServletRequest request , 
			HttpServletResponse response) {
		String path = request.getServletContext().getRealPath("/")+"/upload/board/";
		//C:/java/workspace/.metadata/
		// .plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/model2Study/upload/board/
		File f = new File(path);
		if(!f.exists()) {
			f.mkdirs();
		}
		int size = 10*10*1024;//10M(업로드파일의 최대크기)
		MultipartRequest multi = null;
		try {
			//form을 enctype=multipart/form-data로 전달 시
			//request를 사용할수없음!!!MultipartRequest을 이용해받아서사용하자
			multi = new MultipartRequest(request, path,size,"UTF-8");
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		Board board = new Board();
		board.setWriter(multi.getParameter("writer"));
		board.setPass(multi.getParameter("pass"));
		board.setTitle(multi.getParameter("title"));
		board.setContent(multi.getParameter("content"));
		board.setFile1(multi.getFilesystemName("file1")); //업로드된 파일명
		//list에서 boardid를 세션으로등록함.
		String boardid = (String)request.getSession().getAttribute("boardid");
		if(boardid==null) {
			boardid="1"; // 공지사항 기본게시판으로설정
		}
		board.setBoardid(boardid);//게시판종류 1:공지사항 , 2:자유게시판

		if(board.getFile1()==null) {//file을 등록하지않았다면 빈값이 들어감
			board.setFile1("");
		}
		int num = dao.maxnum();//가장큰 키값(num)을 가져옴
		board.setNum(++num); // 게시글 키값(게시글번호)
		board.setGrp(num); // 그룹번호
	
		if(dao.insert(board)) {
			return "redirect:list?boardid="+boardid;
		}
		request.setAttribute("msg", "게시물등록실패");
		request.setAttribute("url",  "writeForm");
		return "alert";
	}

 

BoardDao의 grpStepAdd

public void grpStepAdd(int grp,int grpstep) {
		SqlSession session = MyBatisConnection.getConnection();
		try {
			map.clear();
			map.put("grp", grp);
			map.put("grpstep", grpstep);
			session.getMapper(cls).grpStepAdd(map);

		} catch (Exception e) {
			e.printStackTrace();
		}
		finally {
			MyBatisConnection.close(session);
		}
		
	}

 

BoardMapper의 grpStepAdd SQL문 (이해가안된다면 밑에 사진을 참고해보자)

	//같은 grp에서 grpstep이 자신보다큰 레코드는 grpstep +1
	//답글은 grpstep의 오름차순으로 정렬이된다
	//참고로 넘어오는 grpstep은 무조건0(원본)이 될거임
	@Update("update board set grpstep = grpstep+1 where grp=#{grp} and grpstep > #{grpstep}")
	void grpStepAdd(Map<String, Object> map);

 

list.jsp 리팩토링

<!-- 답글인 경우 grplevel만큼 공백을주자 -->
		<c:if test="${b.grplevel>0}">
			<c:forEach var="i" begin="1" end="${b.grplevel}">
			&emsp;
			</c:forEach>└
		</c:if>	
		<a href="info?num=${b.num}">${b.title}</a></td>

 

 

 

 

 


3) 수정 (Update)

/board/info.jsp에 다음과같은 수정폼으로이동하게해주는 버튼이있음

<tr><td colspan="2" class="w3-center">
	<a href="replyForm?num=${b.num}">[답변]</a>
	<a href="updateForm?num=${b.num}">[수정]</a>
	<a href="deleteForm?num=${b.num}">[삭제]</a>
	<a href="list?boardid=${b.boardid}">[목록]</a>
</td></tr>

updateForm Controller(관리자만 접근할수잇게 함수걸어놈)

@MSLogin("noticeCheck")
@RequestMapping("updateForm")
	public String updateForm(HttpServletRequest request , 
			HttpServletResponse response) {
	int num = Integer.parseInt(request.getParameter("num"));
    //파라미터로받은num을 이용해 객체를반환
	Board b = dao.numSearch(num);
    //객체를 속성으로등록 후 return
	request.setAttribute("b", b);
		return "board/updateForm";
	}

 

updateForm.jsp

<%@ 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>UpdateForm</title>
</head>
<body>
	<form action="update" method="post" enctype="multipart/form-data" name="f">
	<input type="hidden" name="num" value="${b.num}">
	<input type="hidden" name="file2" value="${b.file1}">
	<div class="container">
	<h2 align="center">${(b.boardid eq '1')?"공지사항":"자유게시판"} 수정</h2>
	<table class="table">
			<tr>
				<td>글쓴이</td>
				<td><input type="text" name="writer" value="${b.writer}" class="form-control"></td>
			</tr>
			<tr>
				<td>비밀번호</td>
				<td><input type="password" name="pass" class="form-control"></td>
			</tr>
			<tr>
				<td>제목</td>
				<td><input type="text" name="title" value="${b.title}"  class="form-control"></td>
			</tr>
			<tr>
				<td>내용</td>
				<td><textarea rows="15" name="content" id="content"
						class="form-control">${b.content}"</textarea></td>
			</tr>
			<tr>
				<td>첨부파일</td>
				<td style="text-align:left">
				<c:if test="${!empty b.file1}">
				<div id="file_desc">${b.file1}
				<a href="javascript:file_delete()">[첨부파일 삭제]</a>
				</div>
				</c:if>
				<input type="file" name="file1">
				</td>
			</tr>
			<tr>
				<td colspan="2"><a href="javascript:document.f.submit()" class="btn btn-outline-secondary">[게시물 수정]</a></td>
			</tr>
		</table>
	</div>
	</form>
<script type="text/javascript">
function file_delete() {
	document.f.file2.value="";
	file_desc.style.display="none";
	}
</script>
</body>
</html>

 

 

update부분 Controller

@MSLogin("noticeCheck")
	@RequestMapping("update")
	public String update(HttpServletRequest request , 
			HttpServletResponse response) {
		String path = request.getServletContext().getRealPath("/")+"/upload/board/";
		File f = new File(path);
		int size = 10*10*1024;//10M(업로드파일의 최대크기)
		MultipartRequest multi = null;
		try {
			//enctype:multipart/form-data로 설정했으므로 일반적으로는 request파라미터를 받을수없음
			//MultipartRequest을 이용해서 받자
			multi = new MultipartRequest(request, path,size,"UTF-8");
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		Board b = new Board();
		int num = Integer.parseInt(multi.getParameter("num"));
		String pass = multi.getParameter("pass");
		b.setNum(num);
		b.setFile1(multi.getFilesystemName("file1"));
		b.setWriter(multi.getParameter("writer"));
		b.setPass(pass);
		b.setTitle(multi.getParameter("title"));
		b.setContent(multi.getParameter("content"));
		b.setRegdate(new Date());

		//변경한 파일이없다면(변경한 파일만 file1에 들어감)
		if(b.getFile1()==null || b.getFile1().equals("")) {
			//이전 첨부파일(file2) 유지
			b.setFile1(multi.getParameter("file2"));
		}


		Board DBb = dao.numSearch(num);
		if(!DBb.getPass().equals(pass)) { //비밀번호오류시
			request.setAttribute("msg", "비밀번호오류");
			request.setAttribute("url", "updateForm?num="+num);
			return "alert";
		}
		if(dao.update(b)) { //수정성공
			return "redirect:info?num="+num;
		}
		else {
			request.setAttribute("msg", "수정실패");
			request.setAttribute("url", "updateForm?num="+num);
			return "alert";
		}	
	}

 

BoardDao의 update(Board)메서드

public boolean update(Board b) {
		SqlSession session = MyBatisConnection.getConnection();
		try {
			return session.getMapper(cls).update(b);

		} catch (Exception e) {
			e.printStackTrace();
		}
		finally {
			MyBatisConnection.close(session);
		}
		return false;
	}

 

BoardMapper의update(Board) 

	@Update("update board set file1=#{file1},writer=#{writer},title=#{title},"
			+ " content=#{content} , regdate=#{regdate} where num=${num}")
	boolean update(Board b);

 


 

4)삭제 (deleteForm)

info에서 삭제버튼을 누르면 이동하는 폼

board/deleteForm?num=xx 의 형태로이동

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>DELETE FORM</title>
</head>
<body>
<form action="delete" method="post">
<input type="hidden" name="num" value="${param.num}">
<table class="table">
<tr><td>password:<input type="password" name="pass" class="form-control"></td></tr>
<tr><td><button class="btn btn-danger">게시물삭제</button></td></tr>
</table>
</form>
</body>
</html>

단순하게 비밀번호만 받아낸다 (파라미터num을 name="num"에 가지고있음)

 

 

delete 관련 Controller

	@MSLogin("noticeCheck")
	@RequestMapping("delete")
	public String delete(HttpServletRequest request , 
			HttpServletResponse response) {
		int num = Integer.parseInt(request.getParameter("num"));
		String pass = request.getParameter("pass");
		Board DbBoard = dao.numSearch(num);
		int grp = DbBoard.getGrp();
		int grplevel = DbBoard.getGrplevel()+1;


		if(!DbBoard.getPass().equals(pass)) {
			request.setAttribute("msg", "비밀번호오류");
			request.setAttribute("url", "deleteForm?num="+num);
			return "alert";
		}
		if(dao.grpSearch(grp,grplevel)>0) {
			request.setAttribute("msg", "답변글부터삭제하세요");
			request.setAttribute("url", "list?boardid="+DbBoard.getBoardid());
			return "alert";

		}
		else {
			if(dao.delete(num)) {
				request.setAttribute("msg", "성공");
				request.setAttribute("url", "list?boardid="+DbBoard.getBoardid());
				return "alert";
			}
			else {
				request.setAttribute("msg", "삭제실패");
				request.setAttribute("url", "deleteForm?num="+num);
				return "alert";

			}
		}

	}

 

BoardDao 의 grpSeach(grp,grplevel)메서드와 delete(num)메서드

public int grpSearch(int grp , int grplevel) {
		SqlSession session = MyBatisConnection.getConnection();
		map.clear();
		map.put("grp", grp);
		map.put("grplevel", grplevel);
		try {
			return session.getMapper(cls).grpSearch(map);

		} catch (Exception e) {
			e.printStackTrace();
		}
		finally {
			MyBatisConnection.close(session);
		}
		return 0;
	}


	public boolean delete(int num) {
		SqlSession session = MyBatisConnection.getConnection();
		try {
			return session.getMapper(cls).delete(num)>0;

		} catch (Exception e) {
			e.printStackTrace();
		}
		finally {
			MyBatisConnection.close(session);
		}
		return false;
		
	}

 

BoardMapper인터페이스

grpSeach와 delete 의 sql문

@Select("SELECT ifnull(COUNT(*),0)"
			+ " FROM board"
			+ " where grplevel=#{grplevel} AND grp=#{grp}")
	int grpSearch(Map<String, Object> map);
    //자신의 하위에 답글이있는지 확인할수있는쿼리(자신의grplevel+1이 들어감)
    //없다면 0 이반환될거임

	@Delete("delete from board where num=#{val}")
	int delete(int num);

 

 


5) list 수정

 

관리자가아니면 공지사항에 글을 쓸수없게 하자

 list.jsp 를 일단 수정했다

<c:if test="${boardid != 1 || sessionScope.login=='admin'}">
<tr><td colspan="5" style="text-align:right">
	<p align="right"><a href="writeForm">[글쓰기]</a></p>
</c:if>

 

 

 

 

layout변경 

webapp/layout

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<c:set var="path" value="${pageContext.request.contextPath }"></c:set>
<!DOCTYPE html>
<html>
<head>
<title><sitemesh:write property="title" /></title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
	href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css">
<script
	src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.slim.min.js"></script>
<script
	src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
<script
	src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
	<!-- include summernote css/js -->
<link href="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote.min.js"></script>
	
<style>
.fakeimg {
	height: 200px;
	background: #aaa;
}

.footer {
	display: flex;
	flex-direction: column;
}

.footer_link {
	height: 15%;
	display: flex;
	align-items: center;
}

.footer_link a {
	text-decoration: none;
	color: black;
	font-weight: bold;
	margin: 15px;
}

.footer_company {
	height: 70%;
}

.footer_company>ul {
	list-style: "- ";
	padding-left: 15px;
}

.footer_copyright {
	height: 15%;
	text-align: center
}

.footer>div {
	border-top: 1px solid gray
}
</style>
<sitemesh:write property="head" />
</head>
<body>
	<div class="jumbotron text-center" style="margin-bottom: 0">
		<h1>dongPage</h1>
		<p>남자의 페이지</p>
	</div>
	<nav class="navbar navbar-expand-sm bg-dark navbar-dark">
		<a class="navbar-brand" href="#">목록</a>
		<button class="navbar-toggler" type="button" data-toggle="collapse"
			data-target="#collapsibleNavbar">
			<span class="navbar-toggler-icon"></span>
		</button>
		<div class="collapse navbar-collapse" id="collapsibleNavbar">
			<ul class="navbar-nav">
				<li class="nav-item"><a class="nav-link" href="${path}/member/main">회원관리</a></li>
				<li class="nav-item"><a class="nav-link" href="${path}/board/list?boardid=1">공지사항</a></li>
				<li class="nav-item"><a class="nav-link" href="${path}/board/list?boardid=2">자유게시판</a></li>
				<c:if test="${sessionScope.login != null}">
				<li class="nav-item"><a class="nav-link" href="#">${sessionScope.login}님 하이</a></li>
				<li class="nav-item"><a class="nav-link" href="${path}/member/logout">로그아웃</a></li>
				</c:if>
				<li class="nav-item"><a class="nav-link" href="javascript:history.go(-1)">뒤로가기</a></li>
				
			</ul>
		</div>
	</nav>
	<div class="container" style="margin-top: 30px">
		<sitemesh:write property="body" />
	</div>

	<footer class="footer">
		<div class="footer_link">
			<a href="">이용약관</a> | <a href="">개인정보취급방침</a> | <a href="">인재채용</a> |
			<a href="">고객센터</a>
		</div>
		<div class="footer_company">
			<ul>
				<li>상호명 : DongCompany </li>
				<li>대표자 : 유동곤</li>
				<li>전화 : 010-86948525</li>
				<li>개인정보책임자 : 유동곤 /ddkk8525@gmail.comr</li>
			</ul>
		</div>
		<div class="footer_copyright">Copyright ⓒ dong Company.
			Allrights reserved.</div>
	</footer>
</body>
</html>

 

 

 

 


6) BOOK

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
   <%--
    --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>방명록 글쓰기 화면</title>
<script type="text/javascript">
   function inputcheck(f) {
       if(f.writer.value == '') {
		   alert("방문자를 입력하세요");
		   f.writer.focus();
		   return false;
       }
       if(f.title.value == '') {
		   alert("제목 입력하세요");
		   f.title.focus();
		   return false;
       }
       if(f.content.value == '') {
		   alert("내용 입력하세요");
		   f.content.focus();
		   return false;
       }
       return true;
   }
</script>
</head>
<body>
<form action="bookwrite" method="post" 
      onsubmit="return inputcheck(this)">
<h2>방명록쓰기</h2>
<table class="table">
<tr><td>방문자</td><td><input type="text" name="writer" class="form-control"></td></tr>
<tr><td>제목</td><td><input type="text" name="title" class="form-control"></td></tr>
<tr><td>내용</td>
    <td><textarea rows="10" cols="60" name="content" class="form-control"></textarea></td></tr>
<tr><td colspan="2" align="center">
     <input type="submit" value="글쓰기"></td></tr>
</table></form></body></html>

해당 폼이 작동되도록 

Controller , 객체 , mapper 등 다 만들어보자

 

해당폼은

http://localhost:8080/model2Study/book/

의 url로 작동하게 만들것임