클라우드 융합 Full-stack 웹 개발자 양성과정/Servlet, JSP

Servlet/JSP - 공지사항 작성, 공지사항 상세페이지, 공지사항 수정

thesunset 2022. 11. 14. 17:51

1. 공지사항 작성

관리자만 글 작성 버튼이 보이게 만들기 

 

조건1) 로그인 상태

조건2) 관리자

<% if(loginUser != null && loginUser.getUserId().equals("admin")) { %>
    <div style="width:870px;" align="right">

        <!-- a태그를 버튼 모양을 만들고 싶다면? : 부트스트랩사용-->
        <a class="btn btn-sm btn-info" href="<%=contextPath%>/enrollForm.no">글작성</a>
    </div>
<br><br>

<%}  %>

버튼에 href속성이 없기 때문에 버튼을 눌러서 페이지를 이동시키고 싶으면 
<button  onclick="location.href="요청 url" >글작성</button>을 해줘야 함. 

하지만 ! 번거로우니까 a태그 사용하기 

<WebContent/views/notice>NoticeEnrollForm

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>공지사항 작성 페이지</title>
<style>
	body{
		box-sizing: border-box;
	}
	.outer{
		width: 1000px;
		margin: auto;
		background-color:  #88A201;
		margin-top: 5px;
		color: white;
	}
	
	#enroll-form input, #enroll-form textarea{
		width: 100%;
		box-sizing: border-box;
	}
	#enroll-form>table{
		border: 1px solid wheat;
	}
</style>
</head>
<body>


<%@ include file="../common/menubar.jsp" %>
	
<div class="outer">

	<br> 
	<h2 align="center">공지사항 작성하기</h2>
	<br><br>

	<form action="<%=contextPath%>/insert.no" method="post" id="enroll-form">
	<!-- 내용이 길면 잘릴 수 있으므로 post방식으로 -->

	<table align="center">
		<tr>
			<th width="50">제목</th>
			<td width="580"><input type="text" name="title" required></td>
		</tr>
		<tr>
			<th>내용</th>
			<td></td>
		</tr>
		<tr>
			<td colspan="2">
				<textarea name="content" style="resize:none;" rows="10" required></textarea>
			</td>
		</tr>

	</table>
	<br><br>
	<div align="center">
		<button type="submit" class="btn btn-sm btn-primary">등록하기</button>
		<button type="button" class="btn btn-sm btn-secondary" onclick="history.back();">뒤로가기</button>
	</div>
	<br><br>
</form>

</div>

</body>
</html>

 

 - history.back(); 이전페이지로 돌아가게 해주는 함수

<com.kh.notice.controller>NoticeEnrollFormController

: 공지사항 작성폼을 우회해서 띄워주는 역할

=> localhost:8001/jsp/enrollForm.no

request.getRequestDispatcher("views/notice/NoticeEnrollForm.jsp").forward(request, response);

<views/notice/NoticeEnrollForm.jsp>공지사항 작성 폼 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>공지사항 작성 페이지</title>
<style>
	body{
		box-sizing: border-box;
	}
	.outer{
		width: 1000px;
		margin: auto;
		background-color:  #88A201;
		margin-top: 5px;
		color: white;
	}
	
	#enroll-form input, #enroll-form textarea{
		width: 100%;
		box-sizing: border-box;
	}
	#enroll-form>table{
		border: 1px solid wheat;
	}
</style>
</head>
<body>


<%@ include file="../common/menubar.jsp" %>
	
<div class="outer">

	<br> 
	<h2 align="center">공지사항 작성하기</h2>
	<br><br>

	<form action="<%=contextPath%>/insert.no" method="post" id="enroll-form">
	<!-- 내용이 길면 잘릴 수 있으므로 post방식으로 -->

	<input type="hidden" name="userNo" value="<%=loginUser.getUserNo() %>">

	<table align="center">
		<tr>
			<th width="50">제목</th>
			<td width="580"><input type="text" name="title" required></td>
		</tr>
		<tr>
			<th>내용</th>
			<td></td>
		</tr>
		<tr>
			<td colspan="2">
				<textarea name="content" style="resize:none;" rows="10" required></textarea>
			</td>
		</tr>

	</table>
	<br><br>
	<div align="center">
		<button type="submit" class="btn btn-sm btn-primary">등록하기</button>
		<button type="button" class="btn btn-sm btn-secondary" onclick="history.back();">뒤로가기</button>
		<!-- history.back(); 이전페이지로 돌아가게 해주는 함수 -->
	</div>
	<br><br>
</form>

</div>

</body>
</html>

<com.kh.notice.controller>NoticeInsertController

POST방식
NOTICE 테이블에 INSERT => 추가로 필요한 데이터 -->관리자의 USERNO : 화면에서 hidden으로 함께 전달해줌

1) 인코딩

request.setCharacterEncoding("UTF-8");

2) 값 뽑기

String userNo = request.getParameter("userNo"); //"1"
String noticeTitle = request.getParameter("title"); //"XXXXX"
String noticeContent = request.getParameter("content"); //"XXXXX"

3) VO객체로 가공

Notice n = new Notice();
n.setNoticeWriter(userNo);
n.setNoticeTitle(noticeTitle);
n.setNoticeContent(noticeContent);

4) Service단으로 전달

int result = new NoticeService().insertNotice(n);

5) 결과에 따른 응답페이지 지정

성공 => 공지사항 리스트가 보여지게 넘어주기 중요*******

(방법1) forwarding  

if(result>0) { 
request.getRequestDispatcher("views/notice/NoticeListView.jsp").forward(request, response);

* 문제점 : 넘긴값이 없으므로 list에 null이 담기게 됨 => 즉 조건문에서 list.isEmpty가 NullpointException 발생

(방법2) sendRedirect => 해결방법 NoticeListController.java로 요청하기 

response.sendRedirect(request.getContextPath() + "/list.no");

실패  => 에러페이지 

} else {
    request.setAttribute("errorMsg","공지사항 등록 실패");
    request.getRequestDispatcher("views/common/errorPage.jsp").forward(request, response);
}

<com.kh.notice.model.service>NoticeService

public int insertNotice(Notice n) {

    Connection conn = getConnection();

    int result = new NoticeDao().insertNotice(conn, n);

    if(result>0) commit(conn);
    else rollback(conn);

    close(conn);

    return result;
}

<com.kh.notice.model.dao>NoticeDao

public int insertNotice(Connection conn, Notice n) {

    //INSERT문 -> 처리된 행
    int result = 0; 
    PreparedStatement pstmt = null;

    String sql = prop.getProperty("insertNotice");

    try {
        pstmt = conn.prepareStatement(sql);

        pstmt.setString(1, n.getNoticeTitle());
        pstmt.setString(2, n.getNoticeContent());
        pstmt.setInt(3, Integer.parseInt(n.getNoticeWriter()));

        result = pstmt.executeUpdate();

    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        close(pstmt);
    }

    return result;
}

2. 공지사항 상세페이지

 

조회수를 증가시키는건 조회를 성공했다는 뜻, 애초에 증가식이 실패했다면 조회도 X

> 상세페이지 요청

1) tr요소를 선택을 해서 클릭

<script>
    $(function(){
    	   $('.list-area>tbody>tr').click(function(){
         //**명확하게 선택하기
         	var nno = $(this).children().eq(0).text();

2) 상세페이지로 가는 경로 요청

: "클릭"했을 때 공지사항의 번호(식별값)을 DB로 전달해주어야 함.

** 웬만하면 식별자로 쓸 값은 select시 들고 오기 

=> 해당tr의 자손 중에서 첫 번째 td태그의 값만 필요함 

var nno = $(this).children().eq(0).text();

*** 글 번호를 이용한 요청

=> 대놓고 요청 : get방식 => url에 key와 value를 노출시켜서 보내기

GET방식 : 요청할 url?key=value&key=value

"쿼리스트링"을 이용하기 

예) localhost:8001/jsp/detail.no?nno=글번호

location.href = "<%=contextPath%>/detail.no?nno="+nno;

<com.kh.notice.controller>NoticeDetailController

1) GET방식 -> 인코딩 X

2) request로부터 값뽑기

localhost:8001/jsp/detail.no?nno=글번호

int noticeNo = Integer.parseInt(request.getParameter("nno"));

3) 가공 => 가공따로 필요 X(변수가 하나라서)

4-1)  Service단으로 전달 => 1(클릭했을 때 공지사항 조회 수를 UPDATE)

int result = new NoticeService().increaseCount(noticeNo);

4-2) Service단으로 전달 => 2(UPDATE가 성공했다면 상세조회 요청)

if(result>0) {
    Notice n = new NoticeService().selectNotice(noticeNo);
    request.setAttribute("n", n);
    request.getRequestDispatcher("views/notice/noticeDetailView.jsp").forward(request, response);
}else { //실패 -> 에러페이지
    request.setAttribute("errorMsg", "공지사항 상세조회 실패");
    request.getRequestDispatcher("views/common/errorPage.jsp").forward(request, response);
}

< views/notice/noticeDetailView.jsp >

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@page import="com.kh.notice.model.vo.Notice" %>
<% 
	Notice n = (Notice)request.getAttribute("n");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>공지사항 상세페이지</title>
<style>
	.outer{
		width: 1000px;
		margin: auto;
		background-color:  #88A201;
		margin-top: 5px;
		color: white;
	}

	#detail-area{
		border: 1px solid wheat;
	}
</style>
</head>
<body>
	<%@ include file="../common/menubar.jsp" %>
	
	<div class="outer">
	<br>
	<h2 align="center">공지사항</h2>
	<br><br>
	
	<table id="detail-area" align="center" border="1">
		<tr>
			<th width="80">제목</th>
			<td width="380" colspan="3"><%=n.getNoticeTitle() %></td>
		</tr>
		<tr>
			<th>작성자</th>
			<td><%=n.getNoticeWriter() %></td>
			<td>작성일</td>
			<td><%=n.getCreateDate() %></td>
		</tr>
		<tr>
			<th>내용</th>
			<td colspan="3">
				<p style="height: 150px;"><%=n.getNoticeContent() %></p>
			</td>
		</tr>
	</table>
	<br><br>
	<div align="center">
		<a class="btn btn-sm btn-secondary" href="<%=contextPath%>/list.no">목록가기</a>
	</div>
	<br><br>
	</div>

</body>
</html>

3. 공지사항 수정하기

작성자만 "수정"버튼이 보이게끔지정 

조건1) 로그인이 되어있고,

조건2) 현재 로그인한 사용자가 작성자와 동일할 경우 (즉, admin일경우)

- 뒤로가기 버튼 아래에 버튼 생성

<% if(loginUser != null && loginUser.getUserId().equals(n.getNoticeWriter())) {%>
    <a class="btn btn-sm btn-warning" href="<%=contextPath%>/updateForm.no?nno=<%=n.getNoticeNo()%>">수정</a>
<%} %>

* 사용자가 어떤 게시글을 클릭했는지 알 수 없으므로 NoticeNo(식별값)을 함께 전달해주어야 함!
=> GET방식으로 쿼리스트링해주기

<com.kh.notice.controller>NoticeUpdateController

1) GET방식 -> 인코딩 X

2) request로부터 값뽑기

int noticeNo = Integer.parseInt(request.getParameter("nno"));

3) 가공 => 가공따로 필요 X(변수가 하나라서)

4) Service단으로 전달

상세조회 시 selectNotice메소드를 재활용 => 호출만하면 끝

Notice n = new NoticeService().selectNotice(noticeNo);

n에 글번호, 글제목, 글내용, 작성자아이디, 작성일 

5) 응답뷰지정

request.setAttribute("n", n);

* 참고 : forwarding이랑 sendRedirect방식

- forwarding : 구체적인 파일 디렉토리 경로를 제시해서 응답해야 할 때 
- sendRedirect : contextPath로 시작하는 url을 응답해야할 때 

request.getRequestDispatcher("views/notice/noticeUpdateForm.jsp").forward(request, response);