[동영상강좌] 보아스 - Jsp26_게시판 만들기(파일 다운로드,
Web Shell 공격 방어, 첨부파일의 확장자 검사)
SQL
--조회수 증가 처리
select * from board;
update board set readcount=readcount+1 where num=1;
-- 게시물 번호가 1번인 레코드
--댓글 테이블
create table board_comment (
comment_num number not null primary key,
board_num number not null REFERENCES board(num),
writer VARCHAR2(50) not null,
content clob not null,
reg_date date default sysdate
);
commit;
--1번 게시물에 댓글 작성
insert into BOARD_COMMENT (COMMENT_NUM, BOARD_NUM, WRITER, CONTENT)
VALUES((select nvl(max(num)+1,1) from board_comment), 1, 'kim', '댓글...');
-- 1번 게시물의 댓글 목록
select * from board_comment where board_num=1;
select count(*) from board_comment where board_num=1;
commit;
select
num, writer, subject, reg_date, readcount , filename, filesize,
down, ref, re_step, re_level
, (select count(*) from BOARD_COMMENT where board_num=num) cnt
from BOARD
order by num desc ;
상세화면
BoardController
if(url.indexOf("view.do")!=-1){
//게시물 번호
int num=Integer.parseInt(request.getParameter("num"));
//조회수 증가 처리
dao.plusReadCount(num, request.getSession());
//dao에 자료 요청
BoardDTO dto =dao.view(num);
//출력 페이지로 포워딩
request.setAttribute("dto", dto);
String page="/board/view.jsp";
RequestDispatcher rd=
request.getRequestDispatcher(page);
rd.forward(request, response);
}
dao
//레코드 상세 정보
public BoardDTO view(int num ){
BoardDTO dto=null;
SqlSession session=null;
try{
session=
MybatisManager.getInstance().openSession();
dto=session.selectOne("board.view", num);
}catch(Exception e){
e.printStackTrace();
}finally{
if(session!=null)session.close();
}
return dto;
}
mapper
<!-- 레코드의 상세 정보 -->
<select id="view" resultType="board.dto.BoardDTO">
select * from board where num=#{num}
</select>
view.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="../include/header.jsp" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script src="http://code.jquery.com/jquery-3.2.1.min.js"></script>
<script>
$(function(){
//댓글 목록
comment_list();
//댓글 쓰기
$("#btnSave").click(function(){
var num ='${dto.num}';
var writer=$("#writer");
var content=$("#content");
$.ajax({
type:"post",
url:"${path}/board_servlet/comment_add.do",
data:{
num :num,
writer:writer.val(),
content:content.val()
},
success:function(){
alert("댓글이 저장 되었습니다.");
writer.val("");
content.val("");
comment_list();
}
});
});
//편집 버튼 클릭
$("#btnEdit").click(function(){
document.form1.action="${path}/board_servlet/passwd_check.do";
document.form1.submit();
});
});
function comment_list(){
//view.jsp 페이지가 로딩되면 비동기식 방식으로 자동 호출
$.ajax({
type:"post",
url :"${path}/board_servlet/commentList.do",
data :{
num :'${dto.num}',
},
success:function(result){//콜백함수
//comment_list.jsp 에 출력된 결과가 result에 리턴
//id 가 commentList 안 태그의 innerHTML 변경
$("#commentList").html(result);
}
});
}
</script>
<style type="text/css">
table{
width:700px;
}
</style>
</head>
<body>
<h2>게시물 상세화면</h2>
<form action="" method="post" name="form1">
<table border="1" >
<tr>
<th>날짜</th>
<td>${dto.reg_date }</td>
<th>조회수</th>
<td>${dto.readcount}</td>
</tr>
<tr>
<td>이름</td>
<td colspan="3">${dto.writer}</td>
</tr>
<tr>
<td>제목</td>
<td colspan="3">${dto.subject}</td>
</tr>
<tr>
<td>본문</td>
<td colspan="3">${dto.content}</td>
</tr>
<tr>
<td>비밀번호</td>
<td colspan="3">
<input type="password" name="passwd">
</td>
</tr>
<tr>
<td>첨부파일</td>
<td colspan="3">
<c:if test="${dto.filesize >0 }">
${dto.filename}( ${dto.filesize} bytes )
</c:if>
<a href="${path}/board_servlet/download.do?num=${dto.num}">
[다운로드]
</a>
</td>
</tr>
<tr>
<td colspan="4" align="center">
<input type="hidden" value="${dto.num}" name="num">
<input type="button" value="편집" id="btnEdit">
<c:if test="${param.message=='error'}">
<span style="color:red;">비밀번호가 틀립니다.</span>
</c:if>
</td>
</tr>
</table>
<!-- 댓글 쓰기 -->
<table>
<tr>
<td><input id="writer" placeholder="이름" ></td>
<td rowspan="2">
<button id="btnSave" type="button">확인</button>
</td>
</tr>
<tr>
<td><textarea rows="5" cols="80"
placeholder="댓글 내용을 입력하세요." id="content"></textarea></td>
</tr>
</table>
<!-- 댓글 목록 출력 -->
<div id="commentList"></div>
</form>
</body>
</html>
게시물 상세화면
|
조회수 증가 처리
class BoardDAO
//조회수 증가 처리
public void plusReadCount(int num, HttpSession httpSession){
SqlSession session=null;
try{
//최근 조회 시간 확인
long update_time=0;
//현재 시각
long current_time=System.currentTimeMillis();
//update_time_1-- null 아니면 기존 세션 데이터 가져오기
if(httpSession.getAttribute("update_time_"+num)!=null){
update_time=
(long)httpSession.getAttribute("update_time_"+num);
}else{
//null 이면 세션 생성
httpSession.setAttribute("update_time_"+num, current_time);
}
//최근 조회 시간을 기준으로 일정 시간이 결과했으면
if(current_time-update_time > 10*1000){
session=MybatisManager.getInstance().openSession();
//조회수 증가 처리
session.update("board.plusReadCount",num);
session.commit();
//최근 조회 시간을 업데이트
httpSession.setAttribute("update_time_"+num, current_time);
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(session!=null) session.close();
}
}
board.xml
<!-- 조회수 증가 처리 -->
<update id="plusReadCount">
update board set readcount=readcount+1
where num=#{num}
</update>
댓글 쓰기 / 목록
controller
if(url.indexOf("commentList.do")!=-1){
int board_num =Integer.parseInt(request.getParameter("num"));
List<BoardCommentDTO> list=dao.commentList(board_num);
request.setAttribute("list", list);
String page="/board/comment_list.jsp";
RequestDispatcher rd=
request.getRequestDispatcher(page);
rd.forward(request, response);
}else if(url.indexOf("comment_add.do")!=-1){
BoardCommentDTO dto=new BoardCommentDTO();
int board_num=Integer.parseInt(request.getParameter("num"));
String writer=request.getParameter("writer");
String content=request.getParameter("content");
dto.setBoard_num(board_num);
dto.setWriter(writer);
dto.setContent(content);
//dao 에 댓글 저장 요청
dao.commentAdd(dto);
//페이지 이동은 없음(ajax 에서 처리)
}
dao
//댓글 쓰기
public void commentAdd(BoardCommentDTO dto){
SqlSession session=null;
try{
session=MybatisManager.getInstance().openSession();
session.insert("board.commentAdd", dto);
session.commit();
}catch(Exception e){
e.printStackTrace();
}finally{
if(session!=null)session.close();
}
}
public List<BoardCommentDTO> commentList(int board_num) {
SqlSession session=null;
List<BoardCommentDTO> list=null;
try{
session=MybatisManager.getInstance().openSession();
list=session.selectList("board.commentList", board_num);
}catch(Exception e){
e.printStackTrace();
}finally{
if(session!=null)session.close();
}
return list;
}
mapper
<insert id="commentAdd">
insert into BOARD_COMMENT (COMMENT_NUM, BOARD_NUM, WRITER, CONTENT)
VALUES((select nvl(max(COMMENT_NUM)+1,1) from board_comment), #{board_num},
#{writer}, #{content})
</insert>
<select id="commentList" resultType="board.dto.BoardCommentDTO">
select
comment_num, board_num, writer, content
, to_char(reg_date, 'yyyy-mm-dd hh:mi:ss') reg_date
from board_comment
where board_num=#{board_num}
order by comment_num
</select>
view
comment_list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="../include/header.jsp" %>
<table border="1">
<c:forEach items="${list}" var="row">
<tr>
<td>
${row.writer}
( ${row.reg_date} ) <br>
${row.content}
</td>
</tr>
</c:forEach>
</table>
view.jsp
<!-- 댓글 쓰기 -->
<table>
<tr>
<td><input id="writer" placeholder="이름" ></td>
<td rowspan="2">
<button id="btnSave" type="button">확인</button>
</td>
</tr>
<tr>
<td><textarea rows="5" cols="80"
placeholder="댓글 내용을 입력하세요." id="content"></textarea></td>
</tr>
</table>
<!-- 댓글 목록 출력 -->
<div id="commentList"></div>
자바스크립트
<script>
$(function(){
//댓글 목록
comment_list();
//댓글 쓰기
$("#btnSave").click(function(){
var num ='${dto.num}';
var writer=$("#writer");
var content=$("#content");
$.ajax({
type:"post",
url:"${path}/board_servlet/comment_add.do",
data:{
num :num,
writer:writer.val(),
content:content.val()
},
success:function(){
alert("댓글이 저장 되었습니다.");
writer.val("");
content.val("");
comment_list();
}
});
});
//편집 버튼 클릭
$("#btnEdit").click(function(){
document.form1.action="${path}/board_servlet/passwd_check.do";
document.form1.submit();
});
});
function comment_list(){
//view.jsp 페이지가 로딩되면 비동기식 방식으로 자동 호출
$.ajax({
type:"post",
url :"${path}/board_servlet/commentList.do",
data :{
num :'${dto.num}',
},
success:function(result){//콜백함수
//comment_list.jsp 에 출력된 결과가 result에 리턴
//id 가 commentList 안 태그의 innerHTML 변경
$("#commentList").html(result);
}
});
}
</script>
게시물 상세화면
|
패스워드 체크 후 수정 화면
controller
if(url.indexOf("passwd_check.do")!=-1){
String num =request.getParameter("num");
String passwd=request.getParameter("passwd");
String page="";
if(num!=null && passwd!=null){
String result=dao.passwdCheck(Integer.parseInt(num), passwd);
if(result!=null){//맞으면
page="/board/edit.jsp";//편집 페이지
request.setAttribute("dto", dao.view(Integer.parseInt(num)));
RequestDispatcher rd=
request.getRequestDispatcher(page);
rd.forward(request, response);
}else{//틀리면 상세 페이지로 이동
page=contextPath+"/board_servlet/view.do?"
+ "num="+num+"&message=error";
response.sendRedirect(page);
}
}
//비밀번호 체크
public String passwdCheck(int num, String passwd){
String result=null;
SqlSession session=null;
try{
session=
MybatisManager.getInstance().openSession();
//num 과 passwd 2개를 전달, map 사용
Map<String, Object> map=new HashMap<>();
//map에 자료 저장 map.put("변수명", 값)
map.put("num", num);
map.put("passwd", passwd);
result=session.selectOne("board.pass_check", map);
}catch(Exception e){
e.printStackTrace();
}finally{
if(session!=null) session.close();
}
return result;
}
댓글 ( 4)
댓글 남기기