Spring3.2에서 작성한 게시판 구현(글 삭제) 입니다. 이
참에 Spring Framework 정복 하세요~
열공하세요~ 자바개발자 여러분!!
오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크,
안드로이드, 아이폰, 닷넷 실무전문 강의)
1. 시작하기
- 이번에는 게시글 삭제 기능을 구현하자.
- JSP쪽 /jsp/delete.jsp 파일이
추가된다.
2. 글을 삭제하기 위한 DAO쪽 클래스를 작성하자.
BoardDAO.java
인터페이스, SpringBoardDAO.java
클래스에 글 삭제를 위한 deleteBoard()
메소드를 추가하자.
소스 코드 중 빨강색 부분이 추가된 부분
[BoardDAO.java]
package
onj.board.dao;
import
java.util.List;
import
onj.board.model.BoardDTO;
import
onj.board.model.CommentDTO;
import org.springframework.dao.DataAccessException;
public interface BoardDAO
{
//게시물
리스트
보기
public List<BoardDTO>
boardList() throws
DataAccessException;
//게시물
본문
미리보기
public String preView(String
seq) throws
DataAccessException;
//게시물
본문
읽기
public BoardDTO
readContent(String seq) throws DataAccessException;
//읽은
글의
조회수
1증가
public int
updateReadCount(String seq) throws DataAccessException;
//Comment저장
public int
insertComment(CommentDTO commentDTO) throws DataAccessException ;
//Comment조회
public
List<CommentDTO> commentList(String seq) throws DataAccessException;
//게시글
입력
public int
insertBoard(BoardDTO board) throws DataAccessException;
//글
수정
public int
updateBoard(BoardDTO board) throws DataAccessException;
//글
삭제
public int
deleteBoard(String sid , String password) throws DataAccessException;
}
[SpringBoardDAO.java]
package
onj.board.dao;
import
java.sql.ResultSet;
import
java.sql.SQLException;
import
java.util.List;
import
javax.sql.DataSource;
import
onj.board.model.BoardDTO;
import
onj.board.model.CommentDTO;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
public class SpringBoardDAO implements BoardDAO {
private JdbcTemplate
jdbcTemplate;
public void
setDataSource(DataSource dataSource)
{
this.jdbcTemplate =
new
JdbcTemplate(dataSource);
}
// /게시판
전체
리스트
보기(list.html)
public List<BoardDTO>
boardList() throws DataAccessException
{
List<BoardDTO>
boardList = null;
String sql = "select *
from board";
boardList =
jdbcTemplate.query(sql, new RowMapper()
{
public Object
mapRow(ResultSet rs, int rowNum) throws SQLException {
BoardDTO
board = new BoardDTO();
board.setSeq(rs.getInt("seq"));
board.setName(rs.getString("name"));
board.setPasswd(rs.getString("passwd"));
board.setTitle(rs.getString("title"));
board.setContent(rs.getString("content"));
board.setFileName(rs.getString("filename"));
board.setRegDate(rs.getString("regdate"));
board.setReadCount(rs.getInt("readcount"));
board.setReply(rs.getInt("reply"));
board.setReply_step(rs.getInt("reply_step"));
board.setReply_level(rs.getInt("reply_level"));
return
board;
}
});
return boardList;
}
// 게시물
본문내용
미리보기(/preView)
public String preView(String
seq) throws DataAccessException
{
String sql = "select *
from board where seq =
?";
String preContent =
(String)
jdbcTemplate.queryForObject(sql,
new
Object[] { seq }, new RowMapper()
{
public Object mapRow(ResultSet rs, int rowNum)
throws SQLException
{
return
rs.getString("content");
}
});
return preContent;
}
// 게시판
상세보기,
게시글
읽기
public BoardDTO
readContent(String seq) throws DataAccessException {
String sql = "select *
from board where seq =
?";
BoardDTO boardDTO =
(BoardDTO)
jdbcTemplate.queryForObject(sql,
new
Object[] { seq }, new RowMapper()
{
public Object mapRow(ResultSet rs, int rowNum)
throws SQLException
{
BoardDTO board = new
BoardDTO();
board.setSeq(rs.getInt("seq"));
board.setName(rs.getString("name"));
board.setPasswd(rs.getString("passwd"));
board.setTitle(rs.getString("title"));
board.setContent(rs.getString("content"));
board.setFileName(rs.getString("filename"));
board.setRegDate(rs.getString("regdate"));
board.setReadCount(rs.getInt("readcount"));
board.setReply(rs.getInt("reply"));
board.setReply_step(rs.getInt("reply_step"));
board.setReply_level(rs.getInt("reply_level"));
return board;
}
});
// 글
조회수
1증가
this.updateReadCount(new Integer(boardDTO.getSeq()).toString());
return boardDTO;
}
// 읽은
글의
조회수를
1증가
public int
updateReadCount(String seq) throws DataAccessException {
String sql = "update
board set readcount = nvl(readcount,0) + 1 where seq = ?";
Object[] obj = { seq
};
return
jdbcTemplate.update(sql,
obj);
}
// 커맨트
입력
public int
insertComment(CommentDTO commentDTO) throws DataAccessException {
String sql = "insert
into comment_t(seq, name, comm) values (?, ?, ?)";
Object[] obj = {
commentDTO.getSeq(), // 게시글순번
commentDTO.getName(),
// 작성자
commentDTO.getComment() };
// 커맨트
return
jdbcTemplate.update(sql,
obj);
}
// 커맨트
조회
public
List<CommentDTO> commentList(String seq) throws DataAccessException {
String sql = "select *
from comment_t where seq =
?";
List<CommentDTO>
commentList =
jdbcTemplate.query(sql,
new
Object[] { seq }, new RowMapper()
{
public Object mapRow(ResultSet rs, int rowNum)
throws SQLException
{
CommentDTO commentDTO = new CommentDTO();
commentDTO.setName(rs.getString("name"));
commentDTO.setComment(rs.getString("comm"));
return commentDTO;
}
});
return commentList;
}
// 글쓰기
public int
insertBoard(BoardDTO board) throws DataAccessException {
String sql = "insert
into board values(board_seq.nextval , ? , ? , ? , ? , ? , sysdate , 0 ,
board_seq.currval , 0 ,
0)";
if
(board.getFileName() == null)
{
Object[] obj =
{ board.getName(),
board.getPasswd(),
board.getTitle(), board.getContent(), "" };
return
jdbcTemplate.update(sql,
obj);
} else {
Object[] obj =
{ board.getName(),
board.getPasswd(),
board.getTitle(), board.getContent(), board.getFileName() };
return
jdbcTemplate.update(sql,
obj);
}
}
// 게시글
수정
public int
updateBoard(BoardDTO board) throws DataAccessException {
String sql = "update
board set title = ? , content = ? where
seq = ?";
Object[] obj = {
board.getTitle(), board.getContent(), board.getSeq() };
return
jdbcTemplate.update(sql,
obj);
}
//
게시글
삭제
public int
deleteBoard(String seq, String passwd)
throws DataAccessException
{
int result = 0;
String sql = "delete
from board where seq = ? and passwd =
?";
result =
jdbcTemplate.update(sql, new Object[] { seq, passwd });
return result;
}
}
3. service
쪽
클래스를
만들어
보자.
소스 코드 중 빨강색 부분이 추가된 부분
[BoardService.java]
package
onj.board.service;
import
java.util.List;
import
onj.board.model.BoardDTO;
import
onj.board.model.CommentDTO;
/*
* 게시판에서 구현할 기능을 인터페이스로 정의
*/
public interface BoardService
{
//게시판 리스트 보기
public List<BoardDTO>
boardList();
//게시물 미리보기
public String preView(String
seq);
//게시판 본문 내용보기, 게시글 읽기
public BoardDTO
readContent(String seq);
//커맨트 입력
public int
insertComment(CommentDTO
commentDTO);
//커맨트 조회
public
List<CommentDTO> commentList(String seq);
//게시글 입력
public int
insertBoard(BoardDTO
board);
//게시글 수정
public int
updateBoard(BoardDTO
board);
//게시글
삭제
public int
deleteBoard(String seq , String
passwd);
}
[BoardServiceImpl.java]
package
onj.board.service;
import
java.util.List;
import
onj.board.dao.BoardDAO;
import
onj.board.model.BoardDTO;
import
onj.board.model.CommentDTO;
public
class BoardServiceImpl implements BoardService {
private BoardDAO boardDAO;
public void setBoardDAO(BoardDAO boardDAO)
{
this.boardDAO =
boardDAO;
}
//게시물 리스트 보기
public List<BoardDTO> boardList() {
return
boardDAO.boardList();
}
//게시물 본문 내용 미리보기
public String preView(String seq) {
return
boardDAO.preView(seq);
}
//게시글 읽기
public BoardDTO readContent(String seq) {
return boardDAO.readContent(seq);
}
//커맨트 입력
public int insertComment(CommentDTO
commentDTO) {
return
boardDAO.insertComment(commentDTO);
}
//커맨트 조회
public List<CommentDTO>
commentList(String seq)
{
return boardDAO.commentList(seq);
}
//게시글 입력
public int insertBoard(BoardDTO board) {
return boardDAO.insertBoard(board);
}
//게시글 수정
public int updateBoard(BoardDTO board) {
return boardDAO.updateBoard(board);
}
//게시글
삭제
public int
deleteBoard(String seq, String passwd)
{
return
boardDAO.deleteBoard(seq,
passwd);
}
}
4. 이번에는 컨트롤러를
수정하자.
소스 코드 중 빨강색 부분이 추가된 부분
[BoardMultiController.java]
package
onj.board.controller;
import
java.io.PrintWriter;
import
java.util.Enumeration;
import
java.util.List;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
onj.board.model.BoardDTO;
import
onj.board.model.CommentDTO;
import
onj.board.service.BoardService;
import
org.springframework.web.servlet.ModelAndView;
import
org.springframework.web.servlet.mvc.multiaction.MultiActionController;
import
com.oreilly.servlet.MultipartRequest;
import
com.oreilly.servlet.multipart.DefaultFileRenamePolicy;
/*
* MultiActionController는
비슷하거나
관련있는
로직을
수행하는
* 다수의
액션을
가지고
있을
때
사용하는
컨트롤러
* 연관된
요청(Request)를
묶을
때
용이함
*/
public
class
BoardMultiController extends
MultiActionController {
private
BoardService boardService;
public
void
setBoardService(BoardService boardService) {
this.boardService =
boardService;
}
//
게시판
리스트
보기,
페이징
기능은
구현
안함
public
ModelAndView list(HttpServletRequest req, HttpServletResponse res)
throws
Exception {
ModelAndView mv = new
ModelAndView("list",
"list",
boardService.boardList());
return
mv;
}
//
게시글
읽기
public
ModelAndView read(HttpServletRequest req, HttpServletResponse res)
throws
Exception {
String seq =
req.getParameter("seq");
ModelAndView mav = new
ModelAndView("read",
"read",
boardService.readContent(seq));
//
해당
글의
커맨트도
함께
내려
보내자.
mav.addObject("comments",
boardService.commentList(seq));
return
mav;
}
//
커맨트쓰기
public
ModelAndView comment(HttpServletRequest req, HttpServletResponse res)
{
String seq =
req.getParameter("seq");
CommentDTO commentDTO =
new
CommentDTO();
commentDTO.setSeq(seq);
commentDTO.setName(req.getParameter("name"));
commentDTO.setComment(req.getParameter("comment"));
boardService.insertComment(commentDTO);
return
new
ModelAndView("redirect:/read.html?seq=" +
seq);
}
//
새글(게시글)
입력
public
ModelAndView write(HttpServletRequest req, HttpServletResponse res)
throws
Exception {
MultipartRequest multi =
new
MultipartRequest(req, "c:\\java\\project\\onjboard1\\upload",
5 * 1024 * 1024,
"euc-kr",
new
DefaultFileRenamePolicy());
Enumeration formNames =
multi.getFileNames();
String formName = (String)
formNames.nextElement();
String fileName =
multi.getFilesystemName(formName);
String name =
multi.getParameter("name");
String passwd =
multi.getParameter("passwd");
String title =
multi.getParameter("title");
String content =
multi.getParameter("content");
BoardDTO board = new
BoardDTO(name, passwd, title, content, fileName);
boardService.insertBoard(board);
return
new
ModelAndView("redirect:/list.html");
}
//
게시글
수정
public
ModelAndView update(HttpServletRequest req, HttpServletResponse res)
throws
Exception {
String seq =
req.getParameter("seq");
String name =
req.getParameter("name");
String passwd =
req.getParameter("passwd");
String title =
req.getParameter("title");
String content =
req.getParameter("content");
BoardDTO board = new
BoardDTO(name, passwd, title, content, "");
board.setSeq(Integer.parseInt(seq));
boardService.updateBoard(board);
return
new
ModelAndView("redirect:/read.html?seq=" +
req.getParameter("seq"));
}
//게시글
삭제
public ModelAndView
delete(HttpServletRequest req, HttpServletResponse res)
throws Exception {
String seq =
req.getParameter("seq");
String passwd =
req.getParameter("passwd");
int result =
boardService.deleteBoard(seq,
passwd);
if (result != 1) {
PrintWriter out
= res.getWriter();
out.println("<script>alert('password
not
correct');</script>");
out.println("<script>history.go(-1);</script>");
return null;
}
else {
return new
ModelAndView("redirect:/list.html");
}
}
}
5. read.jsp를 수정하자.
삭제 버튼을 클릭 시 이동할
주소 확인!
[read.jsp]
<%@ page contentType="text/html;
charset=euc-kr" language="java"
errorPage="" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>게시물
읽기</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<script>
function
write_ok(){
writeform.submit();
}
function
update_ok(){
document.viewform.action =
'/onjboard1/update.html';
document.viewform.submit();
}
</script>
</head>
<body>
<div style="width:600px;">
<div style="float:enter;">
<table width="600" height="420" border="1" align="center">
<tr height="20"><h2>오엔제이프로그래밍실무교육센터
게시판</h2></tr>
<form
name="viewform"
method="post">
<input type="hidden" name="seq" value="${read.seq}">
<input type="hidden" name="reply" value="${read.reply}">
<input type="hidden" name="reply_step" value="${read.reply_step}">
<input type="hidden" name="reply_level" value="${read.reply_level}">
<tr>
<td width="100">* 이름</td>
<td width="500">: <input name="name" type="text" value="${read.name}" size="50" readonly>
</td>
</tr>
<tr>
<td>*
제목</td>
<td>:
<input name="title" type="text" value="${read.title}" size="50" ></td>
</tr>
<tr
align="center">
<td colspan="2"><textarea
name="content" cols="80" rows="12" >${read.content}</textarea></td>
</tr>
<tr>
<td>*
파일</td>
<td>:
<c:choose>
<c:when test="${read.fileName !=
null}">
${read.fileName}
</c:when>
<c:when test="${read.fileName ==
null}">
파일
없음
</c:when>
</c:choose>
</td>
</tr>
<tr>
<td> </td>
<td><input name="button" type="button" on_click="location.href='/reply.html?seq=${read.seq}'" value="답변">
|
<input name="button" type="button" on_click="update_ok()"
value="수정">
<input
name="button" type="button"
on_click="location.href='/onjboard1/jsp/delete.jsp?seq=${read.seq}'"
value="삭제">
|
<input name="button" type="button" on_click="location.href='/onjboard1/list.html'" value="목록"></td>
</tr>
</form>
<tr>
<td height="99" colspan="2">
<!--
BoardMultiController의
comment() 메소드
호출
-->
<form method="post" action="comment.html">
<table border="1">
<tr>
<td>이름 :
</td>
<td><input type="text" name="name"></td>
<td>코멘트:</td>
<td><input type="text" name="comment"></td>
<td><input type="submit" name="Button" value="쓰기"></td>
</tr>
</table>
<input type="hidden" name="seq" value="${read.seq}">
</form>
<!-- 달려있는
커맨트
보기
-->
<table width="789" border="1">
<c:forEach var="comment" items="${comments}">
<tr>
<td width="42" align="center">*</td>
<td width="86">${comment.name}</td>
<td width="639">${comment.comment}</td>
</tr>
</c:forEach>
</table>
</td>
</tr>
</table>
<br><br>
<table><tr><td><tr><b>http://www.onjprogramming.co.kr</tr></td></tr></table>
</div>
</div>
</body>
</html>
6. /jsp/delete.jsp 작성.
[delete.jsp]
<%@ page contentType="text/html;
charset=euc-kr" language="java"
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>오엔제이프로그래밍실무교육센터
게시물
삭제</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<script>
function
del_ok(){
if(document.delform.passwd.value
== ""){
alert("비밀번호를 입력하세요.");
document.delform.passwd.focus();
return
false;
}
delform.submit();
}
</script>
</head>
<body>
<form method="post" name="delform" action="/onjboard1/delete.html">
<table border="1" align="center">
<tr>
<td>비밀번호</td>
<td><input type="text" name="passwd"></td>
<td><input type="button" value="확인" on_click="del_ok();">
<input name="button" type="button" value="취소" on_click="history.back();"></td>
</tr>
</table>
<table align="center"><tr><td><a href="/onjboard1/list.html">목록보기</a></td></tr></table>
<input type="hidden" name="seq" value="${param.seq}">
</form>
</body>
</html>
7. action-servlet.xml을 수정하자.
소스 코드 중 빨강색 부분이 추가된 부분
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
<beans>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@127.0.0.1:1521:onj</value>
</property>
<property name="username">
<value>scott</value>
</property>
<property name="password">
<value>tiger</value>
</property>
</bean>
<!--
넘어오는
URL에
따라
컨트롤러에서
실행될
메소드
매핑
-->
<!--
PropertiesMethodNameResolver는 prop
key로
넘어오는
url에
대해
실행할
컨트롤러의
메소드
정의
-->
<bean id="userControllerMethodNameResolver"
class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
<property name="mappings">
<props>
<!--
list.html 요청이
오면
컨트롤러의 list
메소드
실행
-->
<prop key="/list.html">list</prop>
<!--
read.html 요청이
오면
컨트롤러의 read
메소드
실행
-->
<prop key="/read.html">read</prop>
<!--
comment.html 요청이
오면
컨트롤러의
comment 메소드
실행
-->
<prop key="/comment.html">comment</prop>
<!--
write.html 요청이
오면
컨트롤러의 write
메소드
실행
-->
<prop key="/write.html">write</prop>
<!--
update.html 요청이
오면
컨트롤러의
update 메소드
실행
-->
<prop key="/update.html">update</prop>
<!--
delete.html 요청이
오면
컨트롤러의 delete
메소드
실행 -->
<prop
key="/delete.html">delete</prop>
</props>
</property>
</bean>
<!--
뷰
리졸버
-->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<!--
컨트롤러
매핑
-->
<bean name="/list.html /read.html /comment.html /write.html
/update.html /delete.html"
class="onj.board.controller.BoardMultiController">
<property name="methodNameResolver">
<ref local="userControllerMethodNameResolver" />
</property>
<property name="boardService">
<ref bean="boardService" />
</property>
</bean>
</beans>
실행결과 및 현재까지 만들어진 이클립스
구조
(게시판 리스트보기 + 게시물 본문내용 미리 보기 +
게시글 상세보기 + 커멘트기능 + 글쓰기 + 글
수정하기 + 글 삭제하기)
댓글 없음:
댓글 쓰기