JSP - 미니프로젝트(5. 공지사항 목록, 글쓰기,글 상세, )

이번에는 공지사항 목록 조회, 공지사항 글쓰기, 공지사항 글 상세 페이지작업입니다.

 

우선 공지사항 목록 조회

 

1. 공지사항 목록 조회

Notice = vo

package notice.model.vo;

import java.util.Date;

public class Notice {

	private int nno;
	private String nTitle;
	private String nContent;
	private String nWriter;
	private int nCount;
	private Date nDate;
	private String status;
	
	public Notice() {}

	public Notice(int nno, String nTitle, String nContent, String nWriter, int nCount, Date nDate, String status) {
		super();
		this.nno = nno;
		this.nTitle = nTitle;
		this.nContent = nContent;
		this.nWriter = nWriter;
		this.nCount = nCount;
		this.nDate = nDate;
		this.status = status;
	}

	public Notice(String nTitle, String nContent, String nWriter) {
		super();
		this.nTitle = nTitle;
		this.nContent = nContent;
		this.nWriter = nWriter;
	}

	public int getNno() {
		return nno;
	}

	public void setNno(int nno) {
		this.nno = nno;
	}

	public String getnTitle() {
		return nTitle;
	}

	public void setnTitle(String nTitle) {
		this.nTitle = nTitle;
	}

	public String getnContent() {
		return nContent;
	}

	public void setnContent(String nContent) {
		this.nContent = nContent;
	}

	public String getnWriter() {
		return nWriter;
	}

	public void setnWriter(String nWriter) {
		this.nWriter = nWriter;
	}

	public int getnCount() {
		return nCount;
	}

	public void setnCount(int nCount) {
		this.nCount = nCount;
	}

	public Date getnDate() {
		return nDate;
	}

	public void setnDate(Date nDate) {
		this.nDate = nDate;
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	@Override
	public String toString() {
		return "Notice [nno=" + nno + ", nContent=" + nContent + ", nWriter=" + nWriter + ", nCount=" + nCount
				+ ", nDate=" + nDate + ", status=" + status + "]";
	}
	
	
	
}

 

 

NoticeListServlet.java = > 요청매핑 (/notion/list)

목록 조회할때는 post로할필요없이 그냥 doGet으로 처리하였다.

우선 서비스 -> 다오 로 데이터를보내 List형식으로 반환을 받는방식이다.

List형식으로 반환받아 공지사항목록 jsp페이지로 포워딩한다

포워딩할때 반환받은 listNotice 의 값으로 request 시켜준다.

 

package notice.controller;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import notice.model.vo.Notice;
import notice.service.NoticeService;

@WebServlet("/notice/list")
public class NoticeListServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public NoticeListServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		List<Notice> listNotice = new NoticeService().selectNotice();
		
		if(listNotice != null) {
			request.setAttribute("listNotice", listNotice);
			request.getRequestDispatcher("/WEB-INF/views/notice/noticeListView.jsp").forward(request, response);
		}
		
		
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

 

NoticeService.java

public class NoticeService {
	private NoticeDAO nd = new NoticeDAO();
	
	// 1. 게시판 목록 조회
	public List<Notice> selectNotice(){
		Connection conn = getConnection();
		
		List<Notice> listNotice = nd.selectNotice(conn);
		
		close(conn);
		
		return listNotice;
	}
}

 

NoticeDAO.java

우선 커넥션연결은 기존처럼 JDBCTemplate 에 모아서사용중이다.

그리고 쿼리문도 xml파일에 종합적으로모아서 사용하고있다.

1.공지사항 목록 조회하는 부분이다.

전체 쿼리를 반환받아 List<Notice> 으로 저장하고 반환한다.

public class NoticeDAO {
	private Properties query = new Properties();
	
	public NoticeDAO() {
		String fileName = NoticeDAO.class.getResource("/sql/notice/notice-query.xml").getPath();
		
		try {
			query.loadFromXML(new FileInputStream(fileName));
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

	// 공지사항 목록 조회
	public List<Notice> selectNotice(Connection conn) {
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String sql = query.getProperty("selectNotice");
		List<Notice> listNotice = null;
		
		try {
			listNotice = new ArrayList<>();
			pstmt = conn.prepareStatement(sql);
			
			rs = pstmt.executeQuery();
			
			while(rs.next()) {
				listNotice.add(new Notice(
											rs.getInt("NNO")
										  , rs.getString("NTITLE")
										  , rs.getString("NCONTENT")
										  , rs.getString("NWRITER")
										  , rs.getInt("NCOUNT")
										  , rs.getDate("NDATE")
										  , rs.getString("STATUS")
										  )
							);
			}
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			close(rs);
			close(pstmt);
		}
		
		return listNotice;
	}
}

생각보다 간단한데 ..생각보다 손이많이가는거같다 ..

 

결과값

 

1. 공지사항 글쓰기

방식은 이러하다

공지사항 목록에서 글쓰기버튼은 로그인된 관리자계정(admin)만 보인다.

글쓰기 버튼을 클릭할시 공지사항 글쓰기 페이지로 이동된다.

제목과 내용을 입력후 글쓰기 버튼을누르게되면 

저장된 세션에서 유저의 번호, 제목 , 내용을 요청하는식으로 작업을 진행한다.

그리고 글쓰기에 성공했을시 목록페이지이동하고

글쓰기 실패하면 글쓰기에 실패했다는 에러페이지로 이동한다.

 

 

NoticeInsert.java

id,title, content 값 저장후 매개변수로 보내 Notice객체로 전달받는다.

package notice.controller;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import member.model.vo.Member;
import notice.model.vo.Notice;
import notice.service.NoticeService;

@WebServlet("/notice/insert")
public class NoticeInsert extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public NoticeInsert() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.getRequestDispatcher("/WEB-INF/views/notice/noticeInsertView.jsp").forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		
		String id = ((Member) request.getSession().getAttribute("userLogin")).getUserId();
		String title = request.getParameter("title");
		String content = request.getParameter("content");
		
		Notice n = new Notice(title, content, id);
		
		int result = new NoticeService().insertNotice(n);
		// System.out.println(result);
		
		if(result > 0) {
			request.getSession().setAttribute("msg", "게시글이 등록되었습니다.");
			response.sendRedirect(request.getContextPath() + "/notice/list");
		}else {
			request.setAttribute("session", "게시글이 등록되지 않았습니다.");
			request.getRequestDispatcher("/WEB-INF/views/common/errorpage.jsp");
		}
		
	}

}

 

NoticeService.java

public class NoticeService {
	private NoticeDAO nd = new NoticeDAO();
	
	
	
	// 2. 게시글 등록
	public int insertNotice(Notice n) {
		Connection conn = getConnection();
		
		int result = nd.insertNotice(conn, n);
		
		if(result > 0) {
			commit(conn);
		}else {
			rollback(conn);
		}
		
		close(conn);
		
		return result;
	}
 }

 

NoticeDAO.java

public class NoticeDAO {
	private Properties query = new Properties();
	
	public NoticeDAO() {
		String fileName = NoticeDAO.class.getResource("/sql/notice/notice-query.xml").getPath();
		
		try {
			query.loadFromXML(new FileInputStream(fileName));
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}



	// 2. 게시글 등록
	public int insertNotice(Connection conn, Notice n) {
		PreparedStatement pstmt = null;
		int result = 0;
		String sql = query.getProperty("insertNotice");
		
		try {
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, n.getnTitle());
			pstmt.setString(2, n.getnContent());
			pstmt.setString(3, n.getnWriter());
			
			result = pstmt.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			close(pstmt);
		}
		
		return result;
	}

 

noticeInsertView.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>공지사항 작성</title>
<style>
.outer {
	width: 800px;
	margin: auto;
}

.wrap {
	width: 780px;
	margin: 100px auto;
}

.notice_title {
	border-bottom: 1px solid #282A35;
}

.notice_content {
	padding: 0px 20px;
}

.notice_content .content {
	margin-bottom: 30px;
}

.input_area {
	border: solid 1px #dadada;
	padding: 10px 10px 14px 10px;
	background: white;
}

.input_area input {
	width: 700px;
	height: 30px;
	border: 0px;
}

.input_area input:focus {
	outline: none;
}

.textarea {
	resize: none;
	border: solid 1px #dadada;
}

.textarea:focus {
	outline: none;
}

.title_span {
	background-color: #282A35;
}

.notice_area button {
	width: 100px;
	height: 35px;
	border: 0px;
	color: white;
	background: #282A35;
	margin: 5px;
}

.btn_area {
	text-align: center;
	border-top: 1px solid #282A35;
	padding: 30px;
}
</style>
</head>
<body>
	<jsp:include page="/WEB-INF/views/common/header.jsp" />
	<div class="outer">
		<div class="wrap">
			<div class="notice_area">
				<div class="notice_title">
					<h1>공지사항 작성</h1>
				</div>
				<div class="notice_content">
					<form action="${contextPath }/notice/insert" method="post">
						<div class="content">
							<h4>
								<span class="title_span">&nbsp;</span> 제목
							</h4>
							<span class="input_area"> <input type="text" name="title"
								required>
							</span>

							<h4>
								<span class="title_span">&nbsp;</span> 내용
							</h4>
							<textarea class="textarea" rows="20" cols="100" name="content"
								required></textarea>
						</div>
						<div class="btn_area">
							<button type="button">목록으로</button>
							<button type="submit">작성하기</button>
						</div>
					</form>
				</div>
			</div>
		</div>
	</div>
</body>
</html>

 

결과창

정상적으로 출력되는것 확인할수있다.

 

공지사항 상세

로직은 이러하다.

만약 게시판의 1줄의 라인을 클릭하게되면 

상세페이지로 이동한다.

근데 여기서 클릭할때 get방식으로 nno(게시글번호) 를 파라미터로 넘겨주게된다.

그넘겨준 값으로 데이터베이스와 연동을진행한다.

1. 상세페이지 이동시 게시글의 조회수 +1 해준다.

2. 조회수 +1 성공하면 게시글상세페이지에서 결과값을 표현해준다.

 

NoticeDetailServlet.java

package notice.controller;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import notice.model.vo.Notice;
import notice.service.NoticeService;

@WebServlet("/notice/detail")
public class NoticeDetailServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public NoticeDetailServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		int nno = Integer.parseInt(request.getParameter("nno"));
		
		Notice n = new NoticeService().detailNotice(nno);
		
		if(n != null) {
			request.setAttribute("n", n);
			request.getRequestDispatcher("/WEB-INF/views/notice/noticeDetailView.jsp").forward(request, response);
		}else {
			request.setAttribute("msg", "정삭적인 경로를 이용해주세요.");
			request.getRequestDispatcher("/WEB-INF/views/common/errorpage.jsp");
		}
		
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

 

NoticeService.java

public class NoticeService {
	private NoticeDAO nd = new NoticeDAO();
	
	public Notice detailNotice(int nno) {
		
		Connection conn = getConnection();
		
		// 조회수 먼저 가져오기
		Notice n = null;
		int result = nd.countNotice(conn, nno);
		// System.out.println(result);
		if(result > 0) {
			// 게시글 조회하기
			n = nd.detailNotice(conn, nno);
			
			commit(conn);
		}else {
			rollback(conn);
		}

		close(conn);
		
		return n;
	}
	
	
	
}

 

NoticeDAO.java

package notice.model.dao;

import static common.JDBCTemplate.close;

import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import notice.model.vo.Notice;

public class NoticeDAO {
	private Properties query = new Properties();
	
	public NoticeDAO() {
		String fileName = NoticeDAO.class.getResource("/sql/notice/notice-query.xml").getPath();
		
		try {
			query.loadFromXML(new FileInputStream(fileName));
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

	public int countNotice(Connection conn, int nno) {
		PreparedStatement pstmt = null;
		int result = 0;
		String sql = query.getProperty("countNotice");
		
		try {
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, nno);
			
			result = pstmt.executeUpdate();
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			close(pstmt);
		}
		
		return result;
	}

	public Notice detailNotice(Connection conn, int nno) {
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String sql = query.getProperty("detailNotice");
		Notice n = null;
		
		try {
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, nno);
			
			rs = pstmt.executeQuery();
			
			if(rs.next()) {
				n = new Notice(
						rs.getInt("NNO")
						, rs.getString("NTITLE")
						, rs.getString("NCONTENT")
						, rs.getString("NWRITER")
						, rs.getInt("NCOUNT")
						, rs.getDate("NDATE")
						, rs.getString("STATUS")
						);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			close(rs);
			close(pstmt);
		}
		
		return n;
	}

}

 

noticeDetailView.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>공지사항</title>
<style>
.outer {
	width: 800px;
	margin: auto;
}

.wrap {
	width: 780px;
	margin: 100px auto;
}

.notice_title {
	border-bottom: 1px solid #282A35;
}

.notice_content {
	padding: 0px 20px;
}

.notice_content .subject {
	height: 55px;
	line-height: 55px;
	display: flex;
	justify-content: space-between;
	border-bottom: 1px solid #f3f5f7;
}

.notice_content .content {
	height: 500px;
	overflow: auto;
	margin-bottom: 30px;
}

.title_span {
	background-color: #282A35;
}

.notice_area button {
	width: 100px;
	height: 35px;
	border: 0px;
	color: white;
	background: #282A35;
	margin: 5px;
}

.btn_area {
	text-align: center;
	border-top: 1px solid #282A35;
	padding: 30px;
}
</style>
</head>
<body>
	<jsp:include page="/WEB-INF/views/common/header.jsp" />
	<div class="outer">
		<div class="wrap">
			<div class="notice_area">
				<div class="notice_title">
					<h1>공지사항</h1>
				</div>
				<div class="notice_content">
					<div class="subject">
						<span> 글번호 : ${ n.nno }</span>
						<span> 작성일 : ${ n.nDate }</span>
					</div>
					<div>
						<h4>
							<span class="title_span">&nbsp;</span> 제목
						</h4>
						<p>${ n.nTitle }</p>

						<h4>
							<span class="title_span">&nbsp;</span> 내용
						</h4>
						<pre class="content">${ n.nContent }</pre>
					</div>
					<div class="btn_area">
						<button type="button" onclick="location.href='${contextPath}/notice/list'">목록으로</button>
					</div>
				</div>
			</div>
		</div>
	</div>
</body>
</html>

 

결과값

 

  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유