웹개발 교육/jsp

[53~54일] jsp (20) - myweb 프로젝트(게시판-검색)

ewok 2022. 10. 13. 17:48

게시판에는 보통 검색 기능이 있다.

https://www.egovframe.go.kr/home/ntt/nttList.do

 

bbsList.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="ssi.jsp"%>
<%@ include file="../header.jsp"%>
<!-- 본문 시작 bbsLIst.jsp-->
<h3>* 글 목록 *</h3>
<p><a href="bbsForm.jsp">[글쓰기]</a></p>
<div>
	<table class="table">
	<thead>
		<tr class="success">
			<th>제목</th>
			<th>조회수</th>
			<th>작성자</th>
			<th>작성일</th>
		</tr>
	</thead>
	<tbody>
<%
	ArrayList<BbsDTO> list = dao.list();
	if(list==null){
		out.println("<tr>");
		out.println("	<td colspan='4'>");
		out.println("		<strong>관련자료 없음!!</strong>");
		out.println("	</td>");
		out.println("</tr>");
	} else {
		
		//오늘 날짜를 문자열 "2022-10-22" 만들기
		String today = Utility.getDate();
		
		for(int i=0; i<list.size(); i++) {
			dto = list.get(i);
%>
			<tr>
				<td style="text-align: left">
<%
					//답변이미지 출력
					for(int n=1; n<=dto.getIndent(); n++){
						out.println("<img src='../images/reply.gif'>");
					}//for end

%>													
					<a href="bbsRead.jsp?bbsno=<%=dto.getBbsno()%>"><%=dto.getSubject()%></a>
<%
					//오늘 작성한 글제목 뒤에 new 이미지 출력
					//작성일(regdt)에서 "년월일"만 자르기
					String regdt = dto.getRegdt().substring(0, 10);
					if(regdt.equals(today)){ //작성일과 오늘 날짜가 같다면
						out.println("<img src='../images/new.gif'>");
					}//if end
					
					//조회수가 10 이상이면 hot이미지 출력
					if(dto.getReadcnt()>=10) {
						out.println("<img src='../images/hot.gif'>");
					}//if end
%>					
				</td>
				<td><%=dto.getReadcnt()%></td>
				<td><%=dto.getWname()%></td>
				<td><%=dto.getRegdt().substring(0, 10)%></td>
			</tr>
<%
		}//for end
		
		//글갯수
		int totalRecord = dao.count2(col, word);
		out.println("<tr>");
		out.println("	<td colspan='4' style='text-align:center;'>");
		out.println("		글갯수:<strong> " + totalRecord + " </strong>");
		out.println("	</td>");
		out.println("</tr>");
%>
		<!-- 검색 시작 -->
		<tr>
			<td colspan="4" style="text-align:center; height: 50px;">
				<form action="bbsList.jsp" onsubmit="return searchCheck()"><!-- myscript.js 함수 작성함 -->
					<select name="col">
						<option value="subject_content">제목+내용
						<option value="subject">제목
						<option value="content">내용
						<option value="wname">작성자
					</select>
					<input type="text" name="word" id="word">
					<input type="submit" value="검색" class="btn btn-primary">
				</form>
			</td>
		</tr>
		<!-- 검색 끝 -->
<%		
	}//if end
%>	
	</tbody>
	</table>
</div>
<!-- 본문 끝 -->
<%@ include file="../footer.jsp"%>

조회된 글 개수도 표시되게 할 것인데, 앞서 만들었던 count() 대신 count2()를 만들어 사용하겠다.

 

검색 기능은 페이지마다 자주 사용하는 기능이니 ssi.jsp에 추가하자

 

ssi.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%-- ssi.jsp 공통코드 --%>

<%@ page import="java.sql.*"%>
<%@ page import="java.io.*"%>
<%@ page import="java.util.*"%>

<%@ page import="net.utility.*"%>
<%@ page import="net.bbs.*"%>

<jsp:useBean id="dao" class="net.bbs.BbsDAO" scope="page"></jsp:useBean>
<jsp:useBean id="dto" class="net.bbs.BbsDTO" scope="page"></jsp:useBean>

<%request.setCharacterEncoding("UTF-8");%>

<%
	//검색
	String word = request.getParameter("word"); //검색어
	String col = request.getParameter("col"); //검색칼럼
	word = Utility.checkNull(word); //문자열 값이 null이면 빈문자열로 치환
	col = Utility.checkNull(col);
	
%>

 

bbsDAO.java

public int count2(String col, String word) {
    int cnt = 0;
    try {
        con = dbopen.getConection();

        sql = new StringBuilder();
        sql.append(" SELECT COUNT(*) as cnt ");
        sql.append(" FROM tb_bbs ");

        if(word.length()>=1) { //검색어 존재한다면
            String search = "";
            if(col.equals("subject_content")) {
                search += " WHERE subject LIKE '%" + word + "%' ";
                search += " OR content LIKE '%" + word + "%' ";
            } else if(col.equals("subject")) {
                search += " WHERE subject LIKE '%" + word + "%' ";
            } else if(col.equals("content")) {
                search += " WHERE content LIKE '%" + word + "%' ";
            } else if(col.equals("wname")) {
                search += " WHERE wname LIKE '%" + word + "%' ";
            }//if end
            sql.append(search);
        }//if end

        pstmt = con.prepareStatement(sql.toString());
        rs = pstmt.executeQuery();
        if(rs.next()) {
            cnt = rs.getInt("cnt");
        }//if end

    } catch (Exception e) {
        System.out.println("검색 글갯수 실패:" + e);
    } finally {
        DBClose.close(con, pstmt, rs);
    }//end
    return cnt;
}//count2() end

 

bbsList.jsp에서 검색어를 입력해야 전송 가능하도록 searchCheck() 함수를 걸었다.

 

myscript.js

function searchCheck() {
	//검색어를 입력해야만 서버로 전송
	let word = document.getElementById("word").value;
	word = word.trim();
	if(word.length==0){
		alert("검색어를 입력해 주세요");
		return false;
	}//if end
	
	return true;
}//searchCheck() end

 

 

 

이제 검색어가 포함된 글 목록이 나오게 하자

bbsList.jsp에서 list() 대신 list2()를 새로 만들어할 것이다.(공부를 위해 list()를 그대로 남긴다)

 

BbsDAO.java

public ArrayList<BbsDTO> list2(String col, String word) {
    ArrayList<BbsDTO> list = null;
    try {
        con = dbopen.getConection();

        sql = new StringBuilder();
        sql.append(" SELECT bbsno, wname, subject, readcnt, regdt, indent ");
        sql.append(" FROM tb_bbs ");

        if(word.length()>=1) { //검색어 존재한다면
            String search = "";
            if(col.equals("subject_content")) {
                search += " WHERE subject LIKE '%" + word + "%' ";
                search += " OR content LIKE '%" + word + "%' ";
            } else if(col.equals("subject")) {
                search += " WHERE subject LIKE '%" + word + "%' ";
            } else if(col.equals("content")) {
                search += " WHERE content LIKE '%" + word + "%' ";
            } else if(col.equals("wname")) {
                search += " WHERE wname LIKE '%" + word + "%' ";
            }//if end
            sql.append(search);
        }//if end

        sql.append(" ORDER BY grpno DESC, ansnum ASC ");

        pstmt = con.prepareStatement(sql.toString());
        rs = pstmt.executeQuery();
        if(rs.next()) {
            list = new ArrayList<>();
            do {
                BbsDTO dto = new BbsDTO(); //한줄담기
                dto.setBbsno(rs.getInt("bbsno"));
                dto.setWname(rs.getString("wname"));
                dto.setSubject(rs.getString("subject"));
                dto.setReadcnt(rs.getInt("readcnt"));
                dto.setRegdt(rs.getString("regdt"));
                dto.setIndent(rs.getInt("indent"));
                list.add(dto); //list 저장
            } while(rs.next());
        }//if end			

    } catch (Exception e) {
        System.out.println("전체목록실패:" + e);
    } finally {
        DBClose.close(con, pstmt, rs);
    }//end
    return list;
}//list2() end

 

 

 

그런데 아래 이미지와 같이 글을 본 후 글 목록을 클릭하면 검색이 풀리면서 전체 글 목록들이 나타난다. 글 목록을 눌러 나가도 검색이 유지되도록 해보자

 

 

 

 

bbsList.jsp

bbsRead.jsp로 넘어갈 때 col과 word 변수를 가지고 가야 한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="ssi.jsp"%>
<%@ include file="../header.jsp"%>
<!-- 본문 시작 bbsLIst.jsp-->
<h3>* 글 목록 *</h3>
<p><a href="bbsForm.jsp">[글쓰기]</a></p>
<div>
	<table class="table">
	<thead>
		<tr class="success">
			<th>제목</th>
			<th>조회수</th>
			<th>작성자</th>
			<th>작성일</th>
		</tr>
	</thead>
	<tbody>
<%
	ArrayList<BbsDTO> list = dao.list2(col, word);
	if(list==null){
		out.println("<tr>");
		out.println("	<td colspan='4'>");
		out.println("		<strong>관련자료 없음!!</strong>");
		out.println("	</td>");
		out.println("</tr>");
	} else {
		
		//오늘 날짜를 문자열 "2022-10-22" 만들기
		String today = Utility.getDate();
		
		for(int i=0; i<list.size(); i++) {
			dto = list.get(i);
%>
			<tr>
				<td style="text-align: left">
<%
					//답변이미지 출력
					for(int n=1; n<=dto.getIndent(); n++){
						out.println("<img src='../images/reply.gif'>");
					}//for end

%>													
					<a href="bbsRead.jsp?bbsno=<%=dto.getBbsno()%>&col=<%=col%>&word=<%=word%>"><%=dto.getSubject()%></a>
<%
					//오늘 작성한 글제목 뒤에 new 이미지 출력
					//작성일(regdt)에서 "년월일"만 자르기
					String regdt = dto.getRegdt().substring(0, 10);
					if(regdt.equals(today)){ //작성일과 오늘 날짜가 같다면
						out.println("<img src='../images/new.gif'>");
					}//if end
					
					//조회수가 10 이상이면 hot이미지 출력
					if(dto.getReadcnt()>=10) {
						out.println("<img src='../images/hot.gif'>");
					}//if end
%>					
				</td>
				<td><%=dto.getReadcnt()%></td>
				<td><%=dto.getWname()%></td>
				<td><%=dto.getRegdt().substring(0, 10)%></td>
			</tr>
<%
		}//for end
		
		//글갯수
		int totalRecord = dao.count2(col, word);
		out.println("<tr>");
		out.println("	<td colspan='4' style='text-align:center;'>");
		out.println("		글갯수:<strong> " + totalRecord + " </strong>");
		out.println("	</td>");
		out.println("</tr>");
%>
		<!-- 검색 시작 -->
		<tr>
			<td colspan="4" style="text-align:center; height: 50px;">
				<form action="bbsList.jsp" onsubmit="return searchCheck()"><!-- myscript.js 함수 작성함 -->
					<select name="col">
						<option value="subject_content">제목+내용
						<option value="subject">제목
						<option value="content">내용
						<option value="wname">작성자
					</select>
					<input type="text" name="word" id="word">
					<input type="submit" value="검색" class="btn btn-primary">
				</form>
			</td>
		</tr>
		<!-- 검색 끝 -->
<%		
	}//if end
%>	
	</tbody>
	</table>
</div>
<!-- 본문 끝 -->
<%@ include file="../footer.jsp"%>

 

이제 bbsRead.jsp에서 글목록을 클릭해서 bbsList.jsp로 넘어갈 때 다시 col과 word 변수를 가지고 넘어가게 해야 한다.

col과 word는 ssi.jsp에 값을 가져올 수 있도록 코드를 작성해놨다.

ssi.jsp

 

bbsRead.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="ssi.jsp"%>
<%@ include file="../header.jsp"%>
<!-- 본문 시작 bbsRead.jsp-->
<h3>*게시판 상세보기 *</h3>
<p>
	<a href="bbsForm.jsp">[글쓰기]</a>
	&nbsp;&nbsp;
	<a href="bbsList.jsp?col=<%=col%>&word=<%=word%>">[글목록]</a>
</p>
<div class="container">
<%
	int bbsno = Integer.parseInt(request.getParameter("bbsno"));
	dto = dao.read(bbsno);
	if(dto==null){
		out.print("해당 글 없음!!");
	} else {
		dao.incrementCnt(bbsno); //조회수 증가
%>
		<table class="table">
		<tr>
			<th class="success">제목</th>
			<td><%=dto.getSubject()%></td>
		</tr>
		<tr>
			<th class="success">내용</th>
			<td style="text-align: left">
<%
				//특수문자로 치환하기
				//사용자가 입력한 엔터를 <br>태그로 바꾸기
				String content = Utility.convertChar(dto.getContent());
				out.print(content);
%>			
			</td>
		</tr>		
		<tr>
			<th class="success">조회수</th>
			<td><%=dto.getReadcnt()%></td>
		</tr>
		<tr>
			<th class="success">작성자</th>
			<td><%=dto.getWname()%></td>
		</tr>
		<tr>
			<th class="success">작성일</th>
			<td><%=dto.getRegdt()%></td>
		</tr>
		<tr>
			<th class="success">IP</th>
			<td><%=dto.getIp()%></td>
		</tr>								
		</table>
		<br>
		<input type="button" value="답변쓰기" class="btn btn-info" onclick="location.href='bbsReply.jsp?bbsno=<%=bbsno%>'">
		<input type="button" value="수정" class="btn btn-warning" onclick="location.href='bbsUpdate.jsp?bbsno=<%=bbsno%>'">
		<input type="button" value="삭제" class="btn btn-danger" onclick="location.href='bbsDel.jsp?bbsno=<%=bbsno%>'">
<%		
	}//if end
%>
</div>

<!-- 본문 끝 -->
<%@ include file="../footer.jsp"%>

 

 

 

 

글 수정을 한 뒤 목록 페이지로 돌아왔을 때 검색이 유지되도록 해보자

 

우선 상세보기에서 수정 버튼을 클릭했을 때 col과 word를 가져가도록 해야 한다.

 

bbsRead.jsp

<input type="button" value="수정" class="btn btn-warning" onclick="location.href='bbsUpdate.jsp?bbsno=<%=bbsno%>&col=<%=col%>&word=<%=word%>'">

 

다음으로 bbsUpdate.jsp에서 col과 word값을 bbsUpdateProc.jsp로 넘겨줘야 한다.

 

bbsUpdate.jsp

<form name="bbsfrm" id="bbsfrm" method="post" action="bbsUpdateProc.jsp" onsubmit="return bbsCheck()"> <!-- myscript.js -->
    <input type="hidden" name="bbsno" value="<%=bbsno%>">
    <input type="hidden" name="col" value="<%=col%>">
    <input type="hidden" name="word" value="<%=word%>">

 

이제 bbsUpdateProc.jsp에서 bbsList.jsp로 다시 col과 word값을 넘겨주면 된다.

 

bbsUpdateProc.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="ssi.jsp" %>
<%@ include file="../header.jsp"%>
<!-- 본문 시작 bbsDelProc.jsp-->
<!-- 수정 요청한 정보를 가져와서, DB에 가서 행 수정하기 -->
<h3>* 글 수정 *</h3>

<%
	//수정 요청한 정보 가져오기
	int bbsno = Integer.parseInt(request.getParameter("bbsno"));
	String wname = request.getParameter("wname").trim();
	String subject = request.getParameter("subject").trim();
	String content = request.getParameter("content").trim();
	String passwd = request.getParameter("passwd").trim();
	String ip = request.getRemoteAddr();
	
	//dto에 담기
	dto.setBbsno(bbsno);
	dto.setWname(wname);
	dto.setSubject(subject);
	dto.setContent(content);
	dto.setPasswd(passwd);
	dto.setIp(ip);
	
	int cnt = dao.updateproc(dto);
	if(cnt==0){
		out.println("<p>비밀번호가 일치하지 않습니다</p>");
		out.println("<p><a href='javascript:history.back()'>[다시시도]</a></p>");
	} else {
		out.println("<script>");
		out.println("	alert('게시글이 수정되었습니다.');");
		out.println("	location.href='bbsList.jsp?col=" + col + "&word=" + word + "';"); //목록페이지 이동
		out.println("</script>");
	}//if end
%>	
<!-- 본문 끝 -->
<%@ include file="../footer.jsp"%>