일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- scanner
- dfs
- NIO
- Union-find
- spring boot
- 리소스모니터링
- 스택
- map
- date
- javascript
- deque
- List
- union_find
- Calendar
- BFS
- sql
- Properties
- 스프링부트
- 큐
- string
- priority_queue
- math
- set
- Java
- html
- 힙덤프
- CSS
- JPA
- alter
- GC로그수집
- Today
- Total
매일 조금씩
12/23 - JSP(4) : 게시판 만들기 본문
게시판은 웹프로그래머의 시작이자 끝이다.
기본 게시판 만들기
1. 웹사이트 디자인
Page Navigation(페이지의 흐름)
* 다른 사이트 벤치마킹
* wireframe
* html + link
* 숨겨진 페이지(순수 프로그램으로 구현된 페이지) 찾기
→ 데이터 흐름도 같이 짜면 좋은데 한번에 만들어지진 않는다.
글목록
(X)
글쓰기폼 입력
(글번호)
글상세보기
(글번호, 비밀번호, 글자료)
글수정폼 번호, 입력 -> 글상세보기
(글번호, 비밀번호)
글삭제폼 번호, 비밀번호 -> 글목록
2. 테이블 설계(ERD <- UI)
1) 프로젝트별 데이터베이스
2) 프로젝트별 사용자
3) 프로젝트별 데이터베이스에 테이블
3. Eclipse 프로젝트
eclipse 설정
context.xml
lib <- JDBC 드라이버
jsp 파일 (이미지/CSS)
4. 코딩
4-1. 글쓰기
BoardEx01
simple1
글쓰는 폼은 데이터를 안받아와서 request가 필요없지만,
ok 페이지는 db와 연동 작업을 하기 위해 글쓰기 폼에서 입력받은 데이터를 가져와야하기 때문에 request가 필요하다.
따라서 board_write1.jsp는 입력 받은 값을 검사 한 후, board_write1_ok.jsp로 보내기만 하고
board_write1_ok.jsp 는 db와 연동 작업을 한다.
1) db에서 database와 user를 만들어서 권한 설정을 하고, 테이블 만들기
2) 이클립스에서 jdbc 드라이버와 context.xml을 추가한다.
context.xml은 다른것에서 복붙하는데 name, url, username, password를 새로 만든것 대로 바꿔줘야한다.
3) html 디자인 되있는거 가져오기
4) board_write1.jsp 작성
form에서 action과 name 설정해주기
<form action="board_write1_ok.jsp" method="post" name="wfrm">
script문으로 버튼 이벤트 처리 해주기, 입력 요소들 name잘봐두기(script문에서 필요)
<input type="button" id="submit1" value="쓰기" class="btn_write btn_txt01" style="cursor: pointer;" />
script문으로 입력 필수요소들에 대한 id를 설정한 후 입력없으면 입력하라는 이벤트 처리 해주기
그리고 마지막에 document.wfrm.submit(); 로 ok 페이지로 넘어가게 해주기
<script type="text/javascript">
window.onload = function(){
document.getElementById( 'submit1' ).onclick = function(){
if(document.wfrm.info.checked == false){
alert('동의를 하셔야 합니다.');
return false;
}
if(document.wfrm.writer.value.trim() == ''){
alert('글쓴이를 입력 하셔야 합니다.');
return false;
}
if(document.wfrm.subject.value.trim() == ''){
alert('제목을 입력 하셔야 합니다.');
return false;
}
if(document.wfrm.password.value.trim() == ''){
alert('비밀번호를 입력 하셔야 합니다.');
return false;
}
document.wfrm.submit();
};
};
</script>
전체코드
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Insert title here</title>
<link rel="stylesheet" type="text/css" href="../../css/board_write.css">
<script type="text/javascript">
window.onload = function(){
document.getElementById( 'submit1' ).onclick = function(){
if(document.wfrm.info.checked == false){
alert('동의를 하셔야 합니다.');
return false;
}
if(document.wfrm.writer.value.trim() == ''){
alert('글쓴이를 입력 하셔야 합니다.');
return false;
}
if(document.wfrm.subject.value.trim() == ''){
alert('제목을 입력 하셔야 합니다.');
return false;
}
if(document.wfrm.password.value.trim() == ''){
alert('비밀번호를 입력 하셔야 합니다.');
return false;
}
document.wfrm.submit();
};
};
</script>
</head>
<body>
<!-- 상단 디자인 -->
<div class="con_title">
<h3>게시판</h3>
<p>HOME > 게시판 > <strong>게시판</strong></p>
</div>
<div class="con_txt">
<form action="board_write1_ok.jsp" method="post" name="wfrm">
<div class="contents_sub">
<!--게시판-->
<div class="board_write">
<table>
<tr>
<th class="top">글쓴이</th>
<td class="top" colspan="3"><input type="text" name="writer" value="" class="board_view_input_mail" maxlength="5" /></td>
</tr>
<tr>
<th>제목</th>
<td colspan="3"><input type="text" name="subject" value="" class="board_view_input" /></td>
</tr>
<tr>
<th>비밀번호</th>
<td colspan="3"><input type="password" name="password" value="" class="board_view_input_mail"/></td>
</tr>
<tr>
<th>내용</th>
<td colspan="3"><textarea name="content" class="board_editor_area"></textarea></td>
</tr>
<tr>
<th>이메일</th>
<td colspan="3"><input type="text" name="mail1" value="" class="board_view_input_mail"/> @ <input type="text" name="mail2" value="" class="board_view_input_mail"/></td>
</tr>
</table>
<table>
<tr>
<br />
<td style="text-align:left;border:1px solid #e0e0e0;background-color:f9f9f9;padding:5px">
<div style="padding-top:7px;padding-bottom:5px;font-weight:bold;padding-left:7px;font-family: Gulim,Tahoma,verdana;">※ 개인정보 수집 및 이용에 관한 안내</div>
<div style="padding-left:10px;">
<div style="width:97%;height:95px;font-size:11px;letter-spacing: -0.1em;border:1px solid #c5c5c5;background-color:#fff;padding-left:14px;padding-top:7px;">
1. 수집 개인정보 항목 : 회사명, 담당자명, 메일 주소, 전화번호, 홈페이지 주소, 팩스번호, 주소 <br />
2. 개인정보의 수집 및 이용목적 : 제휴신청에 따른 본인확인 및 원활한 의사소통 경로 확보 <br />
3. 개인정보의 이용기간 : 모든 검토가 완료된 후 3개월간 이용자의 조회를 위하여 보관하며, 이후 해당정보를 지체 없이 파기합니다. <br />
4. 그 밖의 사항은 개인정보취급방침을 준수합니다.
</div>
</div>
<div style="padding-top:7px;padding-left:5px;padding-bottom:7px;font-family: Gulim,Tahoma,verdana;">
<input type="checkbox" name="info" value="1" class="input_radio"> 개인정보 수집 및 이용에 대해 동의합니다.
</div>
</td>
</tr>
</table>
</div>
<div class="btn_area">
<div class="align_left">
<input type="button" value="목록" class="btn_list btn_txt02" style="cursor: pointer;" onclick="location.href='board_list1.jsp'" />
</div>
<div class="align_right">
<input type="button" id="submit1" value="쓰기" class="btn_write btn_txt01" style="cursor: pointer;" />
</div>
</div>
<!--//게시판-->
</div>
</form>
</div>
<!-- 하단 디자인 -->
</body>
</html>
<오류>
- '500-내부서버 오류' 라고 뜨면 java 오류
- 버튼이 동작안하거나하면 개발자도구 콘솔창을 봐야함
- 디자인이 이상하면 html이나 css 오류
5) board_write1_ok.jsp 전체 코드
ok 창에 값 받도록 request처리
(필수가 아닌 값은 null로 들어올 수도 있으므로 if문으로 처리해주기)
Connection, PreparedStatement 선언, context.xml 관련 Context, DataSource 선언, 생성 하고
db랑 작업하는거 모두 작성 db에 crud 성공시 flag에 0 대입 (초깃값 1)
flag값에 따라 알림창이랑 이동하는 페이지까지 작성 해주기
swing에서 하는 거랑 똑같다.
다만 swing은 커넥션 풀을 사용 못한다. 커넥션 풀은 톰캣에서 지원하는 것이기 때문이다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="javax.naming.Context" %>
<%@ page import="javax.naming.InitialContext" %>
<%@ page import="javax.naming.NamingException" %>
<%@ page import="javax.sql.DataSource" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.SQLException" %>
<%
request.setCharacterEncoding("utf-8");
String subject = request.getParameter("subject");
String writer = request.getParameter("writer");
// 필수 입력 항목이 아닌 경우
String mail = "";
if(!request.getParameter("mail1").equals("") && !request.getParameter("mail2").equals("")){
mail = request.getParameter("mail1") + "@" + request.getParameter("mail2");
}
String password = request.getParameter("password");
String content = request.getParameter("content");
String wip = request.getRemoteAddr();
Connection conn = null;
PreparedStatement pstmt = null;
// 정상처리 / 비정상 => 결과를 통합처리하기 위한 변수
int flag = 1;
try{
Context iniCtx = new InitialContext();
Context envCtx = (Context)iniCtx.lookup("java:comp/env");
DataSource dataSource = (DataSource)envCtx.lookup("jdbc/mariadb2");
conn = dataSource.getConnection();
String sql = "insert board1 values(0, ?, ?, ?, ?, ?, 0, ?, now())";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, subject);
pstmt.setString(2, writer);
pstmt.setString(3, mail);
pstmt.setString(4, password);
pstmt.setString(5, content);
pstmt.setString(6, wip);
// 일반적으로 0 값은 정상이다.
int result = pstmt.executeUpdate();
if(result == 1){
flag = 0;
}
}catch(NamingException e){
System.out.println("[에러] : "+e.getMessage());
}catch(SQLException e){
System.out.println("[에러] : "+e.getMessage());
}finally{
if(pstmt != null) pstmt.close();
if(conn != null) conn.close();
}
out.println("<script type='text/javascript'>");
if(flag == 0){
out.println("alert('글쓰기에 성공했습니다.');");
out.println("location.href='board_list1.jsp';");
}else{
out.println("alert('글쓰기에 실패했습니다.');");
out.println("history.back();");
}
out.println("</script>");
%>
4-2. 글목록
글쓰기와 비슷하지만 ResultSet이 추가된다. 입력 작업이 없어서 ok 페이지가 없다.
한 페이지에 db검색 등 전부 작성한다. 값 받아올게 없어서 request 필요 없다.
1) 글목록을 출력하는 부분이 어딘지 디자인(html)에서 찾아야함
그부분이 loop를 돌면서 글들을 가져와야하기 때문이다.
2) StringBuffer 사용한다.
while(rs.next()){} 안에
rs.next()별로 seq, subject, writer, wdate, hit 를 getString하여 String 변수에 넣고
그걸 사용하여 반복되는 html문을 StringBuffer 변수에 append한다.
3) 페이지 이동할때 데이터를 가져가야하면 link로 가져간다.
클릭하는 곳의 href의 링크 마지막 부분에 글번호를 가져가야하는 경우 ?seq=" + seq + " 를 추가한다.
그러면 board_view1.jsp 가 아니라 board_view1.jsp?seq=000 으로 이동한다.
4) 글목록이 쫘라락 출력되어야하는 html디자인 부분에 <%= %> 에
글목록을 받아온 String 변수 이름을 넣어 삽입한다.
5) board_list1.jsp 전체 코드
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="javax.naming.Context" %>
<%@ page import="javax.naming.InitialContext" %>
<%@ page import="javax.naming.NamingException" %>
<%@ page import="javax.sql.DataSource" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page import="java.sql.SQLException" %>
<%@ page import="java.util.Calendar" %>
<%
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
int totalRecord = 0;
StringBuffer sbHtml = new StringBuffer();
try{
Context iniCtx = new InitialContext();
Context envCtx = (Context)iniCtx.lookup("java:comp/env");
DataSource dataSource = (DataSource)envCtx.lookup("jdbc/mariadb2");
conn = dataSource.getConnection();
String sql = "select seq, subject, writer, date_format(wdate,'%Y-%m-%d') wdate, hit, datediff(now(), wdate) wgap from board1 order by seq desc";
pstmt = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = pstmt.executeQuery();
// 읽을 위치를 맨 아래로
rs.last();
// 전체 데이터 갯수
totalRecord = rs.getRow();
rs.beforeFirst();
while(rs.next()){
String seq = rs.getString("seq");
String subject = rs.getString("subject");
String writer = rs.getString("writer");
String wdate = rs.getString("wdate");
String hit = rs.getString("hit");
int wgap = rs.getInt("wgap");
sbHtml.append("<tr>");
sbHtml.append(" <td> </td>");
sbHtml.append(" <td>"+ seq +"</td>");
sbHtml.append(" <td class='left'>");
sbHtml.append( "<a href='board_view1.jsp?seq=" + seq + "'> "+ subject + "</a> ");
if(wgap == 0){
sbHtml.append( "<img src='../../images/icon_hot.gif' alt='HOT'></td>");
}
sbHtml.append(" <td>"+ writer +"</td>");
sbHtml.append(" <td>"+ wdate +"</td>");
sbHtml.append(" <td>"+ hit +"</td>");
sbHtml.append(" <td> </td>");
sbHtml.append("</tr>");
}
}catch(NamingException e){
System.out.println("[에러] : "+e.getMessage());
}catch(SQLException e){
System.out.println("[에러] : "+e.getMessage());
}finally{
if(rs != null) rs.close();
if(pstmt != null) pstmt.close();
if(conn != null) conn.close();
}
%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Insert title here</title>
<link rel="stylesheet" type="text/css" href="../../css/board_list.css">
</head>
<body>
<!-- 상단 디자인 -->
<div class="con_title">
<h3>게시판</h3>
<p>HOME > 게시판 > <strong>게시판</strong></p>
</div>
<div class="con_txt">
<div class="contents_sub">
<div class="board_top">
<div class="bold">총 <span class="txt_orange"><%=totalRecord %></span>건</div>
</div>
<!--게시판-->
<div class="board">
<table>
<tr>
<th width="3%"> </th>
<th width="5%">번호</th>
<th>제목</th>
<th width="10%">글쓴이</th>
<th width="17%">등록일</th>
<th width="5%">조회</th>
<th width="3%"> </th>
</tr>
<%= sbHtml %>
<!-- 행시작 -->
<!--
<tr>
<td> </td>
<td>1</td>
<td class="left"><a href="board_view1.jsp">adfas</a> <img src="../../images/icon_hot.gif" alt="HOT"></td>
<td>asdfa</td>
<td>2017-01-31</td>
<td>6</td>
<td> </td>
</tr>
-->
<!-- 행끝 -->
</table>
</div>
<!--//게시판-->
<div class="align_right">
<input type="button" value="쓰기" class="btn_write btn_txt01" style="cursor: pointer;" onclick="location.href='board_write1.jsp'" />
</div>
</div>
</div>
<!--//하단 디자인 -->
</body>
</html>
4-3. 글보기
글번호를 받아와야해서 request 필요하다.
1) list와 거의 비슷하지만 db에서 검색한 결과가 하나이므로 while(rs.next())하지 않고 if(rs.next())를 한다.
2) 아래 html 디자인에 아래와 같이 <%= %> 를 사용하여 추가한다.
<th width="10%">제목</th>
<td width="60%"><%=subject %></td>
3) content에 엔터키가 있어도 출력이 안되므로 content는 다음과 같이 replaceAll을 붙여줘야한다.
content = rs.getString("content").replaceAll("\n","<br />");
4) board_view1.jsp 전체 코드
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="javax.naming.Context" %>
<%@ page import="javax.naming.InitialContext" %>
<%@ page import="javax.naming.NamingException" %>
<%@ page import="javax.sql.DataSource" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page import="java.sql.SQLException" %>
<%
request.setCharacterEncoding("utf-8");
String seq = request.getParameter("seq");
String subject = "";
String writer = "";
String mail = "";
String wip = "";
String wdate = "";
String hit = "";
String content = "";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try{
Context iniCtx = new InitialContext();
Context envCtx = (Context)iniCtx.lookup("java:comp/env");
DataSource dataSource = (DataSource)envCtx.lookup("jdbc/mariadb2");
conn = dataSource.getConnection();
// 조회수 증가를 위한 update
String sql = "update board1 set hit=hit+1 where seq=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, seq);
pstmt.executeUpdate();
sql = "select subject, writer, mail, wip, wdate, hit, content from board1 where seq=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, seq);
rs = pstmt.executeQuery();
// 하나만 가져오니까 if문 사용
if(rs.next()){
subject = rs.getString("subject");
writer = rs.getString("writer");
mail = rs.getString("mail");
wip = rs.getString("wip");
wdate = rs.getString("wdate");
hit = rs.getString("hit");
content = rs.getString("content").replaceAll("\n","<br />");
}
}catch(NamingException e){
System.out.println("[에러] : "+e.getMessage());
}catch(SQLException e){
System.out.println("[에러] : "+e.getMessage());
}finally{
if(rs != null) rs.close();
if(pstmt != null) pstmt.close();
if(conn != null) conn.close();
}
%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Insert title here</title>
<link rel="stylesheet" type="text/css" href="../../css/board_view.css">
</head>
<body>
<!-- 상단 디자인 -->
<div class="con_title">
<h3>게시판</h3>
<p>HOME > 게시판 > <strong>게시판</strong></p>
</div>
<div class="con_txt">
<div class="contents_sub">
<!--게시판-->
<div class="board_view">
<table>
<tr>
<th width="10%">제목</th>
<td width="60%"><%=subject %></td>
<th width="10%">등록일</th>
<td width="20%"><%=wdate %></td>
</tr>
<tr>
<th>글쓴이</th>
<td><%=writer %>(<%=mail %>)(<%=wip %>)</td>
<th>조회</th>
<td><%=hit%></td>
</tr>
<tr>
<td colspan="4" height="200" valign="top" style="padding: 20px; line-height: 160%"><%=content %></td>
</tr>
</table>
</div>
<div class="btn_area">
<div class="align_left">
<input type="button" value="목록" class="btn_list btn_txt02" style="cursor: pointer;" onclick="location.href='board_list1.jsp'" />
</div>
<div class="align_right">
<input type="button" value="수정" class="btn_list btn_txt02" style="cursor: pointer;" onclick="location.href='board_modify1.jsp?seq=<%=seq %>'" />
<input type="button" value="삭제" class="btn_list btn_txt02" style="cursor: pointer;" onclick="location.href='board_delete1.jsp?seq=<%=seq %>'" />
<input type="button" value="쓰기" class="btn_write btn_txt01" style="cursor: pointer;" onclick="location.href='board_write1.jsp'" />
</div>
</div>
<!--//게시판-->
</div>
</div>
<!-- 하단 디자인 -->
</body>
</html>
4-4. 글삭제
글삭제는 글보기와 거의 똑같다. 그러나
그러나 글삭제는 db 검색과 삭제 두가지 작업이 필요하므로 글번호와 비밀번호를 가지고 가야한다.
따라서 db 검색 작업은 board_delete1.jsp에 작성하고, 비밀번호 입력을 통한 글 삭제 작업은
1) 글보기의 html디자인 코드에서 삭제 버튼 부분을 onclick의 href에 ?seq=<%=seq %>를 붙여주는 방식으로 다음과같이 변경한다.
<input type="button" value="삭제" class="btn_list btn_txt02" style="cursor: pointer;" onclick="location.href='board_delete1.jsp?seq=<%=seq %>'" />
2) 글보기의 java 코드를 가져 와서 수정한다.
db에서 writer와 subject만 가져오면 된다.
3) 글번호를 가지고 ok창으로 가야하는데 html 디자인 코드 내에 name이 seq 인 값이 없으므로 아래처럼 hidden으로
숨겨서 가져온다.
<input type="hidden" name="seq" value="<%=seq %>" />
4) 비밀번호를 입력했는지 안했는지 script문에서 검사를 한 후 ok 창으로 넘긴다.
5) board_delete1.jsp 전체 코드
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="javax.naming.Context" %>
<%@ page import="javax.naming.InitialContext" %>
<%@ page import="javax.naming.NamingException" %>
<%@ page import="javax.sql.DataSource" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page import="java.sql.SQLException" %>
<%
request.setCharacterEncoding("utf-8");
String seq = request.getParameter("seq");
String subject = "";
String writer = "";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try{
Context iniCtx = new InitialContext();
Context envCtx = (Context)iniCtx.lookup("java:comp/env");
DataSource dataSource = (DataSource)envCtx.lookup("jdbc/mariadb2");
conn = dataSource.getConnection();
String sql = "select subject, writer from board1 where seq=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, seq);
rs = pstmt.executeQuery();
// 하나만 가져오니까 if문 사용
if(rs.next()){
subject = rs.getString("subject");
writer = rs.getString("writer");
}
}catch(NamingException e){
System.out.println("[에러] : "+e.getMessage());
}catch(SQLException e){
System.out.println("[에러] : "+e.getMessage());
}finally{
if(rs != null) rs.close();
if(pstmt != null) pstmt.close();
if(conn != null) conn.close();
}
%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Insert title here</title>
<link rel="stylesheet" type="text/css" href="../../css/board_write.css">
<script type="text/javascript">
window.onload = function(){
document.getElementById('submit1').onclick = function(){
if(document.dfrm.password.value.trim() == ''){
alert('비밀번호를 입력하셔야 합니다.');
return false;
}
document.dfrm.submit();
}
}
</script>
</head>
<body>
<!-- 상단 디자인 -->
<div class="con_title">
<h3>게시판</h3>
<p>HOME > 게시판 > <strong>게시판</strong></p>
</div>
<div class="con_txt">
<form action="board_delete1_ok.jsp" method="post" name="dfrm">
<input type="hidden" name="seq" value=<%=seq %> />
<div class="contents_sub">
<!--게시판-->
<div class="board_write">
<table>
<tr>
<th class="top">글쓴이</th>
<td class="top" colspan="3"><input type="text" name="writer" value="<%=writer %>" class="board_view_input_mail" maxlength="5" readonly/></td>
</tr>
<tr>
<th>제목</th>
<td colspan="3"><input type="text" name="subject" value="<%=subject %>" class="board_view_input" readonly/></td>
</tr>
<tr>
<th>비밀번호</th>
<td colspan="3"><input type="password" name="password" value="" class="board_view_input_mail"/></td>
</tr>
</table>
</div>
<div class="btn_area">
<div class="align_left">
<input type="button" value="목록" class="btn_list btn_txt02" style="cursor: pointer;" onclick="location.href='board_list1.jsp'" />
<input type="button" value="보기" class="btn_list btn_txt02" style="cursor: pointer;" onclick="location.href='board_view1.jsp?seq=<%=seq %>'" />
</div>
<div class="align_right">
<input type="button" id="submit1" value="삭제" class="btn_write btn_txt01" style="cursor: pointer;" />
</div>
</div>
<!--//게시판-->
</div>
</form>
</div>
<!-- 하단 디자인 -->
</body>
</html>
6) seq와 password를 request로 받아서 문자열 변수에 담는다.
7) 절대 db의 비밀번호를 프로그램으로 가져오지마라.
이말은 즉, select로 가져와서 비교하지마라! 나중에 가서 보안문제 걸린다.
delete할 때 where절에 조건으로 걸어줘라!
8) 비밀번호가 잘못입력된 경우가 있기 때문에 아래처럼 경우의 수가 두개가 된다. flag 초깃값을 2로 해놔야함
int result = pstmt.executeUpdate();
if(result == 0){
// 비밀번호 오류
flag = 1;
}else if(result == 1){
// 정상
flag = 0;
}
그리고 출력은 다음과 같다.
out.println("<script type='text/javascript'>");
if(flag == 0){
out.println("alert('글삭제에 성공했습니다.');");
out.println("location.href='board_list1.jsp;'");
}else if(flag == 1){
out.println("alert('비밀번호가 잘못되었습니다.');");
out.println("history.back();");
}else{
out.println("alert('글쓰기에 실패했습니다.');");
out.println("history.back();");
}
out.println("</script>");
9) board_delete1_ok.jsp 전체 코드
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="javax.naming.Context" %>
<%@ page import="javax.naming.InitialContext" %>
<%@ page import="javax.naming.NamingException" %>
<%@ page import="javax.sql.DataSource" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.SQLException" %>
<%
request.setCharacterEncoding("utf-8");
String seq = request.getParameter("seq");
String password = request.getParameter("password");
Connection conn = null;
PreparedStatement pstmt = null;
// 정상처리 / 비정상 => 결과를 통합처리하기 위한 변수
int flag = 2;
try{
Context iniCtx = new InitialContext();
Context envCtx = (Context)iniCtx.lookup("java:comp/env");
DataSource dataSource = (DataSource)envCtx.lookup("jdbc/mariadb2");
conn = dataSource.getConnection();
String sql = "delete from board1 where seq=? and password=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, seq);
pstmt.setString(2, password);
int result = pstmt.executeUpdate();
if(result == 0){
// 비밀번호 오류
flag = 1;
}else if(result == 1){
// 정상
flag = 0;
}
}catch(NamingException e){
System.out.println("[에러] : "+e.getMessage());
}catch(SQLException e){
System.out.println("[에러] : "+e.getMessage());
}finally{
if(pstmt != null) pstmt.close();
if(conn != null) conn.close();
}
out.println("<script type='text/javascript'>");
if(flag == 0){
out.println("alert('글삭제에 성공했습니다.');");
out.println("location.href='board_list1.jsp';");
}else if(flag == 1){
out.println("alert('비밀번호가 잘못되었습니다.');");
out.println("history.back();");
}else{
out.println("alert('글삭제에 실패했습니다.');");
out.println("history.back();");
}
out.println("</script>");
%>
4-5. 글수정
delete와 거의 비슷하다.
1) subject, writer, content, mail를 db에서 검색 해온다.
2) mail을 가져와서 mail1@mail2형식으로 출력하기 위해서는 mail이 공백인 경우가 있기 때문에 다음과 같이 코딩한다.
String[] mail = null; // 라고 위에 정의되어 있고..
if(rs.getString("mail").equals("")){ // 메일이 없으면
mail = new String[] {"",""}; // 공백을 넣고
}else{ // 메일 주소가 있으면
mail = rs.getString("mail").split("@"); // 쪼개서 넣기
}
3) 글번호를 가지고 ok창으로 가야하는데 html 디자인 코드 내에 name이 seq 인 값이 없으므로 아래처럼 hidden으로
숨겨서 가져온다.
<input type="hidden" name="seq" value="<%=seq %>" />
4) 값 검사에서 password외에 subject가 입력됐는지도 확인해야한다.
5) board_modify1.jsp 전체 코드
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="javax.naming.Context" %>
<%@ page import="javax.naming.InitialContext" %>
<%@ page import="javax.naming.NamingException" %>
<%@ page import="javax.sql.DataSource" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page import="java.sql.SQLException" %>
<%
request.setCharacterEncoding("utf-8");
String seq = request.getParameter("seq");
String subject = "";
String writer = "";
String[] mail = null;
String content = "";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try{
Context iniCtx = new InitialContext();
Context envCtx = (Context)iniCtx.lookup("java:comp/env");
DataSource dataSource = (DataSource)envCtx.lookup("jdbc/mariadb2");
conn = dataSource.getConnection();
String sql = "select subject, writer, content, mail from board1 where seq=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, seq);
rs = pstmt.executeQuery();
// 하나만 가져오니까 if문 사용
if(rs.next()){
subject = rs.getString("subject");
writer = rs.getString("writer");
if(rs.getString("mail").equals("")){
mail = new String[] {"",""};
}else{
mail = rs.getString("mail").split("@");
}
content = rs.getString("content").replaceAll("\n","<br />");
}
}catch(NamingException e){
System.out.println("[에러] : "+e.getMessage());
}catch(SQLException e){
System.out.println("[에러] : "+e.getMessage());
}finally{
if(rs != null) rs.close();
if(pstmt != null) pstmt.close();
if(conn != null) conn.close();
}
%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Insert title here</title>
<link rel="stylesheet" type="text/css" href="../../css/board_write.css">
<script type='text/javascript'>
window.onload = function(){
document.getElementById('submit1').onclick = function(){
if(document.mfrm.subject.value.trim() == ''){
alert('제목을 입력하셔야 합니다.');
return false;
}
if(document.mfrm.password.value.trim() == ''){
alert('비밀번호를 입력하셔야 합니다.');
return false;
}
document.mfrm.submit();
}
}
</script>
</head>
<body>
<!-- 상단 디자인 -->
<div class="con_title">
<h3>게시판</h3>
<p>HOME > 게시판 > <strong>게시판</strong></p>
</div>
<div class="con_txt">
<form action="board_modify1_ok.jsp" method="post" name="mfrm">
<input type="hidden" name="seq" value="<%=seq %>" />
<div class="contents_sub">
<!--게시판-->
<div class="board_write">
<table>
<tr>
<th class="top">글쓴이</th>
<td class="top" colspan="3"><input type="text" name="writer" value="<%=writer %>" class="board_view_input_mail" maxlength="5" readonly/></td>
</tr>
<tr>
<th>제목</th>
<td colspan="3"><input type="text" name="subject" value="<%=subject %>" class="board_view_input" /></td>
</tr>
<tr>
<th>비밀번호</th>
<td colspan="3"><input type="password" name="password" value="" class="board_view_input_mail"/></td>
</tr>
<tr>
<th>내용</th>
<td colspan="3"><textarea name="content" class="board_editor_area"><%=content %></textarea></td>
</tr>
<tr>
<th>이메일</th>
<td colspan="3"><input type="text" name="mail1" value="<%=mail[0] %>" class="board_view_input_mail"/> @ <input type="text" name="mail2" value="<%=mail[1] %>" class="board_view_input_mail"/></td>
</tr>
</table>
</div>
<div class="btn_area">
<div class="align_left">
<input type="button" value="목록" class="btn_list btn_txt02" style="cursor: pointer;" onclick="location.href='board_list1.jsp'" />
<input type="button" value="보기" class="btn_list btn_txt02" style="cursor: pointer;" onclick="location.href='board_view1.jsp?seq=<%=seq %>'" />
</div>
<div class="align_right">
<input type="button" id="submit1" value="수정" class="btn_write btn_txt01" style="cursor: pointer;" />
</div>
</div>
<!--//게시판-->
</div>
</form>
</div>
<!-- 하단 디자인 -->
</body>
</html>
6) subject, content, mail에 대한 update문이 실행된다는 것을 제외하곤 delete_ok와 동일하다.
(writer는 read only이기대문에 수정이 불가능)
7) board_modify1_ok.jsp 전체 코드
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="javax.naming.Context" %>
<%@ page import="javax.naming.InitialContext" %>
<%@ page import="javax.naming.NamingException" %>
<%@ page import="javax.sql.DataSource" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.SQLException" %>
<%
request.setCharacterEncoding("utf-8");
String seq = request.getParameter("seq");
String password = request.getParameter("password");
String subject = request.getParameter("subject");
// 필수 입력 항목이 아닌 경우
String mail = "";
if(!request.getParameter("mail1").equals("") && !request.getParameter("mail2").equals("")){
mail = request.getParameter("mail1") + "@" + request.getParameter("mail2");
}
String content = request.getParameter("content");
Connection conn = null;
PreparedStatement pstmt = null;
// 정상처리 / 비정상 => 결과를 통합처리하기 위한 변수
int flag = 2;
try{
Context iniCtx = new InitialContext();
Context envCtx = (Context)iniCtx.lookup("java:comp/env");
DataSource dataSource = (DataSource)envCtx.lookup("jdbc/mariadb2");
conn = dataSource.getConnection();
String sql = "update board1 set subject = ?, mail=?, content=? where seq=? and password=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, subject);
pstmt.setString(2, mail);
pstmt.setString(3, content);
pstmt.setString(4, seq);
pstmt.setString(5, password);
int result = pstmt.executeUpdate();
if(result == 0){
// 비밀번호 오류
flag = 1;
}else if(result == 1){
// 정상
flag = 0;
}
}catch(NamingException e){
System.out.println("[에러] : "+e.getMessage());
}catch(SQLException e){
System.out.println("[에러] : "+e.getMessage());
}finally{
if(pstmt != null) pstmt.close();
if(conn != null) conn.close();
}
out.println("<script type='text/javascript'>");
if(flag == 0){
out.println("alert('글수정에 성공했습니다.');");
out.println("location.href='board_view1.jsp?seq="+seq+"';");
}else if(flag == 1){
out.println("alert('비밀번호가 잘못되었습니다.');");
out.println("history.back();");
}else{
out.println("alert('글수정에 실패했습니다.');");
out.println("history.back();");
}
out.println("</script>");
%>
>
4-6. 총 건수
list에 코딩한다.
(1) select count(*) from board1;
(2) 메서드 사용
pstmt = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = pstmt.executeQuery();
// 읽을 위치를 맨 아래로
rs.last();
// 전체 데이터 갯수
totalRecord = rs.getRow();
rs.beforeFirst();
위 코드와 같이 pstmt를 수정하고 last(), getRow()를 사용한 후 , 다른 작업을 위해 rs를 beforeFirst()로 다시 위로 올려줘야한다. pstmt는 저렇게 수정해줘야 rs를 맘대로 다룰수 있다.
4-7. 조회수
list에서 글을 선택하여 조회하면 글보기로 이동하므로 view에서 처리한다.
String sql = "update board1 set hit=hit+1 where seq=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, seq);
pstmt.executeUpdate();
위와 같이 view가 실행되면 hit가 +1로 update 되도록 한다.
'빅데이터 플랫폼 구축을 위한 자바 개발자 양성과정' 카테고리의 다른 글
12/28 - JSP(6) : JSP 기본객체, model1기법으로 게시판 만들기 (0) | 2021.01.04 |
---|---|
12/24 - JSP(5) : 최신글 표시, 페이징 있는 게시판 만들기 (0) | 2021.01.04 |
12/22 - JSP(3) : 데이터베이스 연결, 커넥션 풀, 게시판 만들 준비 (0) | 2021.01.04 |
12/21 - JSP(2) : JSP 문법 <%@ %>,<% %>, <%= %> 와 request, 달력만들기(Date, Calendar) (0) | 2020.12.22 |
12/18 - JSP(1) : 이클립스 + 톰캣 설정, 작성, 실행 방법 (0) | 2020.12.22 |