기존 게시판 기능 + Spring 게시판 구현(커멘트
조회, 입력 기능추가)
오라클자바커뮤니티에서 설립한
오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝,
힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)
1.
시작하기
-
이번에는 게시판 상세보기(글읽기) 페이지에서 게시글에 커멘트를 입력하고, 입력되어 있는 커멘트를 글을 게시글
조회 시 같이 조회될 수 있는 기능을 추가해 보자.
2.
먼저 커멘트(Comment) 처리를 위한
CommentDTO.java를 작성하자.
[CommentDTO.java]
package onj.board.model;
public class CommentDTO {
public int seq; //게시글
번호
public String name; //이름
public String comment;//커멘트
public CommentDTO() {}
public CommentDTO(String name, String comment) {
this.name = name;
this.comment = comment;
}
public int getSeq() {
return seq;
}
public void setSeq(int seq) {
this.seq = seq;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
}
3.
먼저 커멘트(Comment) 처리를 위한 DAO쪽 클래스를 작성하자.
BoardDAO.java 인터페이스, SpringBoardDAO.java 클래스에
커멘트
입력, 조회를
위한 insertComment(), commentList() 두개의
메소드를
추가하자.
[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;
}
[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;
}
}
4. 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);
}
[SpringServiceImpl.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);
}
}
5.
이번에는 컨트롤러를 수정하자.
조금 달라진 부분은 게시 글을 읽을 때 해당 글의 커멘트도 같이 화면에 보일 수 있도록 뷰에 커멘트 리스트를 매달아서(addObject해서) 보낸다.
[BoardMultiController.java]
소스
코드
중
빨강색
부분이
커멘트
조회, 입력
기능을
위해
추가된
부분
package onj.board.controller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import onj.board.model.CommentDTO;
import onj.board.service.BoardService;
import
org.springframework.web.servlet.ModelAndView;
import
org.springframework.web.servlet.mvc.multiaction.MultiActionController;
/*
*
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);
}
}
6.
커멘트 기능이 추가된 뷰페이지 read.jsp를 작성하자.
소스
코드
중
빨강색
부분이
커멘트
조회, 입력
기능을
위해
추가된
부분
[read.jsp]
<%@ page contentType="text/html;
charset=euc-kr" language="java"
import="java.sql.*" errorPage="" %>
<%@ page import =
"onj.board.model.* , onj.board.service.* ,
java.util.*" %>
<%@ 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();
}
</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>
<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" readonly></td>
</tr>
<tr align="center">
<td colspan="2"><textarea
name="content" cols="80" rows="12" readonly>${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"
onClick="location.href='./reply.html?seq=${read.seq}'" value="답변">
|
<input name="button"
type="button"
value="수정">
|
<input name="button"
type="button"
onClick="location.href='./delete.jsp?seq=${read.seq}'" value="삭제">
|
<input name="button"
type="button"
onClick="location.href='./list.html'" value="목록"></td>
</tr>
<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>
<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}">
</div>
</div>
</body>
</html>
7.
action-servlet.xml을 수정하자.
소스
코드
중
빨강색
부분이
커멘트
조회, 입력
기능을
위해
추가된
부분
<?xml version="1.0"
encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD
BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<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>
</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" class="onj.board.controller.BoardMultiController">
<property name="methodNameResolver">
<ref local="userControllerMethodNameResolver" />
</property>
<property name="boardService">
<ref bean="boardService" />
</property>
</bean>
</beans>
실행결과
및 현재까지 만들어진 이클립스 구조
(게시판 리스트보기 + 게시물
본문내용 미리 보기 + 게시글 상세보기 + 커멘트기능)
:namespace prefix = v ns = "urn:schemas-microsoft-com:vml"
/>
>