서블릿과 JSP 를 이용하여 목적별 데이트 코스를 추천해 주는 웹을 개발하였다.
제가 맡은 기능은 사용자 간의 커뮤니티인 게시판을 만는 것이었습니다.
Servlet, JSP 로 CRUD 게시판 구현, Ajax 를 통해 비동기식 댓글 CRUD 및
사이드 인기 게시글, 검색 부분을 구현하였습니다.
부가기능으로 관리자가 공지한 글이 커뮤니티 상단에 노출 시켜, 드롭다운 방식으로 게시글을 조회 할 수 있습니다.
03. 게시글 상세페이지 및 댓글 입력
$(function(){
selectTopList(); // 열자 마자 호출 하고
$(".thumbnail").click(function(){
var bno = $(this).children().eq(0).val();
location.href="<%=contextPath%>/detail.bo?bno="+bno;
})
setInterval(selectTopList, 5000)
$("#thumbList").on("click",".thumb",function(){
var bno = $(this).children().eq(0).val();
location.href = "<%=contextPath%>/detail.bo?bno="+bno;
})
})
JSP 화면에서 클래스 이름으로 접근 .thumbnail 클릭하면 상세페이지로 이동
boardDetailServlet
package semiProject.com.kh.board.controller;
import java.io.IOException;
import java.util.ArrayList;
import javax.servlet.RequestDispatcher;
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 semiProject.com.kh.board.model.service.BoardService;
import semiProject.com.kh.board.model.vo.Attachment;
import semiProject.com.kh.board.model.vo.Board;
/**
* Servlet implementation class BoardDetailServlet
*/
@WebServlet("/detail.bo")
public class BoardDetailServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public BoardDetailServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int bno = Integer.parseInt(request.getParameter("bno"));
Board b = new BoardService().selectBoard(bno);
ArrayList<Attachment> fileList = new BoardService().selectThumbnail(bno);
if( b != null ) {
request.setAttribute("b", b);
request.setAttribute("fileList", fileList);
request.getRequestDispatcher("views/board/boardDetails.jsp").forward(request, response);
}else {
request.setAttribute("msg", "사진게시판 상세보기 실패하였습니다.");
request.getRequestDispatcher("views/common/errorPage.jsp").forward(request, response);
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
화면에서 name 값 bno (boarad number) 를 가져와 객체에 인자로 넘겨 찾는다.
Service
public Board selectBoard(int bno) {
Connection conn = getConnection();
int result = new BoardDao().increaseCount(conn,bno);
Board b = null;
if(result > 0) {
commit(conn);
b = new BoardDao().selectBoard(conn, bno);
}else {
rollback(conn);
}
return b;
}
public ArrayList<Attachment> selectThumbnail(int bno) {
Connection conn = getConnection();
ArrayList<Attachment> list = new BoardDao().selectThumbnail(conn, bno);
close(conn);
return list;
}
bno 값으로 각각의 테이블에서 불러와야 하므로 두개 메소드로 나눠 보내진다.
SelectBoard 안에서 조회수 증가처리 위해 두개로 나눠 보내진다.
Dao
public int increaseCount(Connection conn, int bno) {
int result = 0;
PreparedStatement pstmt = null;
String sql = prop.getProperty("increaseCount");
try {
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, bno);
result = pstmt.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
close(pstmt);
}
return result;
}
public Board selectBoard(Connection conn, int bno) {
Board b = null;
PreparedStatement pstmt = null;
ResultSet rset = null;
String sql = prop.getProperty("selectBoard");
try {
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, bno); // 넘버로 조회해 온다.
rset = pstmt.executeQuery();
// 만약에 결과 값이 있으면
if (rset.next()) {
b = new Board(rset.getInt("BOARD_NO"), rset.getString("BOARD_TITLE"), rset.getString("BOARD_CONTENT"),
rset.getString("USER_ID"), rset.getInt("COUNT"), rset.getDate("CREATE_DATE")
);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
close(rset);
close(pstmt);
}
return b;
}
public ArrayList<Attachment> selectThumbnail(Connection conn, int bno) {
ArrayList<Attachment> list = new ArrayList<>();
PreparedStatement pstmt = null;
ResultSet rset = null;
String sql = prop.getProperty("selectAttachment");
// selectAttachment=SELECT FILE_NO, ORIGIN_NAME, CHANGE_NAME FROM ATTACHMENT
// WHERE REF_BNO=? AND STATUS='Y'
try {
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, bno);
rset = pstmt.executeQuery();
while (rset.next()) {
Attachment at = new Attachment();
at.setFileNo(rset.getInt("FILE_NO"));
at.setOriginName(rset.getString("ORIGIN_NAME"));
at.setChangeName(rset.getString("CHANGE_NAME"));
list.add(at);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
close(rset);
close(pstmt);
}
return list;
}
각 쿼리문을 받아온 bno 값으로 처리한다.
쿼리문
selectBoard=SELECT BOARD_NO, BOARD_TITLE, BOARD_CONTENT, USER_ID, COUNT, CREATE_DATE FROM BOARD B JOIN MEMBER ON(BOARD_WRITER = USER_NO)WHERE B.STATUS = 'Y' AND BOARD_NO=?
increaseCount=UPDATE BOARD SET COUNT=COUNT+1 WHERE BOARD_NO=?
selectAttachment=SELECT FILE_NO, ORIGIN_NAME, CHANGE_NAME FROM ATTACHMENT WHERE REF_BNO=? AND STATUS='Y'
상세페이지 화면
<div class="blog__details__comment__form">
<% if(loginUser != null) { %>
<div class="blog__details__comment__title"><h4>댓글 달기</h4></div>
<div class="input-comment">
<textarea rows="5" id="replyContent" style="resize:none; width:100%;"></textarea>
</div>
<button type="submit" class="site-btn" id="addReply">댓글 등록</button>
<% }else{ %>
<div class="input-comment">
<p>Comment</p>
<textarea rows="5" cols="90" id="replyContent" style="resize:none;" readonly="readonly" disabled>로그인한 사용자만 가능한 서비스입니다. 로그인 후 이용해주세요</textarea>
</div>
<button type="submit" class="site-btn" disabled>댓글 등록</button>
<% } %>
<!-- --댓글 달면 보여질 리스트 -->
<br><br>
<section class="content-item" id="comments">
<div class="blog__item__text" id="replyListArea">
<div id="replyList"> <!-- 글이 선택되면 자동으로 댓들이 조회됨 --></div>
</div>
</section>
</div> <!-- 코멘트 섹션 end -->
<!-- 수정 페이제 모달 -->
<div class="modal fade" id="mml" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<div class="modal-body">
<div class="form-group">
<input class="form-control" type="hidden" id="replyNo" name="replyNo" readonly>
</div>
<div class="form-group">
<label for="reply_text">댓글 내용</label> <textarea class="form-control"
id="updateContent" name="replyContent" style="height: 200px" ></textarea>
</div>
<div class="form-group">
<label for="reply_writer">댓글 작성자</label> <input
class="form-control" id="writer" name="replyWriter" readonly>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-dark"
data-dismiss="modal">닫기</button>
<button type="button" class="btn btn-success modalModBtn">수정</button>
</div>
</div>
</div>
</div>
댓글 관련 Ajax 통신 ( 리스트, 입력, 삭제, 수정)
var rlist = [];
$(function(){
selectReplyList(); //글이 조회되면 댓글이조회 되어야 한다.
$("#addReply").click(function(){
if($("#replyContent").val() != "") {
var content = $("#replyContent").val();
var bno = <%=b.getBoardNo()%>;
$.ajax({
url:"rInsert.bo",
type: "post",
data: {
content: content,
bno:bno
},
success:function(status){
if(status == "success"){
selectReplyList();
$("#replyContent").val(""); //컨테츠에 값으 초기화 함
}
},error : function() {
console.log("ajax 통신 실패 - 댓글 등록")
}
})
}else{
alert("댓글 내용을 입력하세요.")
}
})
})
//댓글 생성
function selectReplyList(){
$("#replyList").empty(); //테이블을 비우고
$.ajax({
url: "rList.bo",
type: "get",
data: {
bno: <%=b.getBoardNo() %>
},
success : function(list){
console.log(list);
console.log("${loginUser.userId}")
var value="";
$.each(list, function(i, obj){
rlist.push(obj);
//for(var i in list){
var rno = list[i].replyNo;
var user = list[i].replyWriter;
//console.log(user);
value += '<br><br><p>'+
'<input type="hidden" id="rno" name="rno" value="'+rno+'">'+
list[i].replyContent+
'<ul class="blog__item__widget">'+
'<hr>'+
'<li class="no'+i+'">'+'<i class="fa fa-comment"> '+list[i].replyNo+'</i></li>'+
'<li>'+'<i class="fa fa-clock-o">'+'</i>'
+list[i].createDate+'</li>'+
'<li>'+'<i class="fa fa-user"> '+user+'</i>'
+'</li>';
if("${loginUser.userId}" == user){
value +='<button class="reBtn" onclick="updateForm('+ rno +')" data-toggle="modal" data-target="#mml" style="background-color: green;">수정</button> '+
'<button class="reBtn" onclick="del('+ rno +')" style="background-color: gray;">삭제</button></ul>';
}else{
value += '<br><br><br></ul>';
}
});
$("#replyList").html(value);
},
error:function(){
console.log("ajax 통신 실패 - 댓글 조회");
}
})
}
//댓글 삭제
function del(rno){
if(confirm("정말 삭제 하시겠습니까?") == true){
$.ajax({
url: "deleteComment.bo",
data : {
rno : rno
},
type: "post",
success : function(result){
console.log(result)
selectReplyList();
},
error : function(e){
console.log(e);
}
})
}else{
return;
}
}
function updateForm(rno){
for(var i = 0; i< rlist.length; i++){
var text = rlist[i].replyContent;
var content = text.replace(/(<br>|<br\/>|<br \/>)/g, '\r\n');
if(rno == rlist[i].replyNo){
$("#replyNo").val(rlist[i].replyNo);
$("#updateContent").val(content);
$("#writer").val(rlist[i].replyWriter);
}
}
};
$(".modalModBtn").on("click", function(){
var replyNo = $("#replyNo").val();
var replyContent = $("#updateContent").val();
var content = replyContent.replace('\r\n', /(<br>|<br\/>|<br \/>)/g );
console.log(replyNo)
console.log(replyContent)
$.ajax({
url:"updateReply.bo",
type:"get",
data:{ replyNo : replyNo,
replyContent : content
},
success : function(result){
console.log("결과"+result)
alert("댓글 수정 성공");
selectReplyList();
$("#mml").modal("hide");
}
});
});
ReplyListServlet
package semiProject.com.kh.board.controller;
import java.io.IOException;
import java.util.ArrayList;
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 com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import semiProject.com.kh.board.model.service.BoardService;
import semiProject.com.kh.board.model.vo.Reply;
/**
* Servlet implementation class ReplyListSerjvlet
*/
@WebServlet("/rList.bo")
public class ReplyListSerjvlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ReplyListSerjvlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String boardNo = request.getParameter("bno");
if(boardNo != null)
{
int bno = Integer.parseInt(request.getParameter("bno"));
ArrayList<Reply> list = new BoardService().selectRList(bno);
response.setContentType("application/json; charset=utf-8");
Gson gson = new GsonBuilder().setDateFormat("yyyy년MM월dd일").create();
gson.toJson(list, response.getWriter());
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
bno로 받아온 자바 객체를 toJson 처리 해주는데 응답스트림에서 기록하기 위해 response.getWirter() 선언해 준다.
ReplyInsertSerlvet
package semiProject.com.kh.board.controller;
import java.io.IOException;
import java.io.PrintWriter;
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 semiProject.com.kh.board.model.service.BoardService;
import semiProject.com.kh.board.model.vo.Reply;
import semiProject.com.kh.member.model.vo.Member;
/**
* Servlet implementation class ReplyInsertServlet
*/
@WebServlet("/rInsert.bo")
public class ReplyInsertServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ReplyInsertServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String content = request.getParameter("content");
int bno = Integer.parseInt(request.getParameter("bno"));
int writer = ((Member)request.getSession().getAttribute("loginUser")).getUserNo();
Reply r = new Reply();
r.setReplyContent(content.replaceAll("\n", "<br>"));
r.setRefBoardId(bno);
r.setReplyWriter(String.valueOf(writer));
int result = new BoardService().insertReply(r);
PrintWriter out = response.getWriter();
if(result > 0 ) {
out.print("success");
}else {
out.print("fail");
}
out.flush();
out.close();
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
ReplyUpdateServlet
package semiProject.com.kh.board.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 semiProject.com.kh.board.model.service.BoardService;
import semiProject.com.kh.board.model.vo.Reply;
import semiProject.com.kh.member.model.vo.Member;
/**
* Servlet implementation class ReplyUpdateServlet
*/
@WebServlet("/updateReply.bo")
public class ReplyUpdateServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ReplyUpdateServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String content = request.getParameter("replyContent");
int rno = Integer.parseInt(request.getParameter("replyNo"));
Reply r = new Reply();
r.setReplyContent(content.replaceAll("\n", "<br>"));
r.setReplyNo(rno);
new BoardService().updateReply(r);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
'세미프로젝트' 카테고리의 다른 글
세미 프로젝트[어디어디] (0) | 2021.11.29 |
---|---|
세미프로젝트 [어디어디] (0) | 2021.11.29 |
세미프로젝트 [어디어디] 공지사항 상단 조회 (0) | 2021.11.28 |