2013년 8월 2일 금요일

16. [Spring Framework3.2]스프링 게시판 만들기(글 삭제), Spring Board 예제, 스프링교육, 자바교육, 오라클자바교육, 오에제이프로그래밍

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>
실행결과 및 현재까지 만들어진 이클립스 구조
(게시판 리스트보기 + 게시물 본문내용 미리 보기 + 게시글 상세보기 + 커멘트기능 + 글쓰기 + 글 수정하기 + 글 삭제하기)






댓글 없음:

댓글 쓰기