E. Spring Framework 게시판 만들기 (글입력 + 파일 업로드), 스프링 게시판 소스예제, Spring Framework게시판소스
1. 시작하기
- 이번에는 게시판 리스트 보기에서 “글쓰기” 버튼을 눌렀을 때 게시물울 입력하는 화면과 함께 글을 저장하는
부분을 개발하자.
- MultipartRequest를 사용한 파일 업로드를 위해 http://commons.apache.org/에서commons-fileupload-xx.jar
와 commons-io-xx.jar 파일파일을
다운받자.
2. [root-context.xml]
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Root Context: defines shared resources
visible to all other web components -->
<!-- 파일 업로드 -->
<bean
id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property
name="maxUploadSize" value="90000000"/>
<property
name="defaultEncoding" value="utf-8"/>
</bean>
<bean id="boardDAO"
class="com.board.dao.BoardDAOImple">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<bean id="boardService"
class="com.board.service.BoardServiceImple">
<property name="boardDAO">
<ref bean="boardDAO"/>
</property>
</bean>
<bean id="pageHandler"
class="com.board.util.PageHandler">
<property name="boardDAO">
<ref bean="boardDAO"/>
</property>
</bean>
</beans>
--------------------------------------------------------------------------------------
3. [BoardDAO.java] ,
[BoardDAOImple.java]
package com.board.dao;
import java.util.List;
import java.util.Map;
import org.springframework.dao.DataAccessException;
import com.board.model.BoardDTO;
import com.board.model.CommentDTO;
public interface BoardDAO {
// 전체 게시글 수
public int boardCount(Map<String,
Object>searchMap)throws DataAccessException;
// 게시판 리스트
public List<BoardDTO> boardList(Map<String,
Object>searchMap) throws DataAccessException;
// 게시물 본문 미리보기
public String preView(String seq)throws
DataAccessException;
// 게시글 조회수 1씩증가
public int updateReadCount(String seq)throws
DataAccessException;
// 게시글 상세보기
public BoardDTO readContent(String seq)throws
DataAccessException;
// 코멘트 저장
public int insertComment(CommentDTO
commentDTO)throws DataAccessException;
// 코멘트 조회
public List<CommentDTO> ListComment(String
seq)throws DataAccessException;
// 게시글 입력
public int insertBoard(BoardDTO boardDTO)throws
DataAccessException;
}
--------------------------------------------------------------------------------------
package com.board.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import com.board.model.BoardDTO;
import com.board.model.CommentDTO;
public class BoardDAOImple implements BoardDAO {
private
JdbcTemplate jdbaTemplate;
public void
setDataSource(DataSource dataSource){
this.jdbaTemplate = new
JdbcTemplate(dataSource);
}
// 게시글 수
public int
boardCount(Map<String, Object>searchMap)throws DataAccessException{
int count =
0;
String sql =
"";
if(searchMap.get("boardListSearchText") ==
null){
sql = "select
count(*) from board02";
count =
jdbaTemplate.queryForObject(sql,
Integer.class
);
}else{
String
boardListSelect = (String) searchMap.get("boardListSelect");
String
boardListSearchText = (String) searchMap.get("boardListSearchText");
sql = "select
count(*) from board02 where "+boardListSelect+" like
'%"+boardListSearchText+"%'";
count =
jdbaTemplate.queryForObject(sql,Integer.class);
}
return
count;
}
// 게시판 리스트
public
List<BoardDTO> boardList(Map<String, Object>searchMap) throws
DataAccessException {
List<BoardDTO> boardList = null;
String sql =
"";
Object[]
obj;
if(searchMap.get("boardListSearchText") ==
null){
sql = "select *
from ("
+ " select ROWNUM r,b.seq ,b.name,b.title
,TO_CHAR(b.regdate,'YYYY/MM/DD')as regdate, b.readcount, "
+ " r.reply_level"
+ " from board02 b, reply r"
+ " where b.seq = r.reply"
+ " order by r.reply desc, r.reply_step
asc"
+ " )"
+ " where r BETWEEN ? AND
?";
obj = new
Object[] {searchMap.get("startRow"),searchMap.get("endRow")};
}else{
String
boardListSelect = (String) searchMap.get("boardListSelect");
String
boardListSearchText = (String) searchMap.get("boardListSearchText");
sql = "select *
from ("
+ " select ROWNUM r,b.seq ,b.name,b.title
,TO_CHAR(b.regdate,'YYYY/MM/DD')as regdate, b.readcount, "
+ " r.reply_level"
+ " from board02 b, reply r"
+ " where b.seq = r.reply"
+ " and "+boardListSelect+" like
'%"+boardListSearchText+"%'"
+ " order by r.reply desc, r.reply_step
asc"
+ " )"
+ " where r BETWEEN ? AND
?";
obj = new
Object[] {searchMap.get("startRow"),searchMap.get("endRow")};
}
boardList =
jdbaTemplate.query(sql,
obj,
new RowMapper<BoardDTO>(){
public BoardDTO mapRow(ResultSet rs, int
rowNum)throws SQLException{
BoardDTO boardDTO = new
BoardDTO(rs.getString("seq"),
rs.getString("name"),
rs.getString("title"),
rs.getString("regdate"),
rs.getInt("readcount"),
rs.getInt("reply_level")
);
return boardDTO;
}
});
return
boardList;
}
// 게시물 본문내용
미리보기
public String
preView(String seq) throws DataAccessException{
String sql =
"select content from board02 where seq = ?";
String
preContent = "";
Object obj[] =
{seq};
preContent =
jdbaTemplate.queryForObject(sql,obj,String.class);
return
preContent;
}
// 게시글 조회수
1씩증가
public int
updateReadCount(String seq)throws DataAccessException{
String sql = "
update board02 set readcount = nvl(readcount,0)+1 where seq = ?";
Object[] obj =
{seq};
return
jdbaTemplate.update(sql,obj);
}
// 게시글
상세보기
public BoardDTO
readContent(String seq)throws DataAccessException{
// 조회수 1증가 메소드
호출
this.updateReadCount(seq);
String sql =
"select * from board02 where seq = ?";
Object[] obj =
{seq};
BoardDTO
boardDTO = jdbaTemplate.queryForObject(sql,
obj,
new
RowMapper<BoardDTO>() {
public BoardDTO
mapRow(ResultSet rs,int rowNum)throws SQLException {
BoardDTO
boardDTO = new BoardDTO();
boardDTO.setSeq(rs.getString("seq"));
boardDTO.setName(rs.getString("name"));
boardDTO.setPasswd(rs.getString("passwd"));
boardDTO.setTitle(rs.getString("title"));
boardDTO.setContent(rs.getString("content"));
boardDTO.setFilename(rs.getString("filename"));
boardDTO.setRegdate(rs.getString("regdate"));
boardDTO.setReadcount(rs.getInt("readcount"));
return
boardDTO;
}
});
return
boardDTO;
}
// 코멘트 저장
public int
insertComment(CommentDTO commentDTO) throws DataAccessException {
String sql =
"insert into comment_t02 values(sequence_comment_seq.nextval,?,?,?)";
Object[] obj =
{commentDTO.getComment_name(),commentDTO.getComment_comm(),commentDTO.getSeq()};
return
jdbaTemplate.update(sql, obj);
}
// 코멘트 조회
public
List<CommentDTO> ListComment(String seq) throws DataAccessException
{
String sql =
"select * from comment_t02 where seq = ?";
Object[] obj =
{seq};
List<CommentDTO> list =
jdbaTemplate.query(sql,
obj,
new RowMapper<CommentDTO>(){
public
CommentDTO mapRow(ResultSet rs,int rowNum)throws SQLException {
CommentDTO
commentDTO = new CommentDTO();
commentDTO.setComment_seq(rs.getString("comment_seq"));
commentDTO.setComment_name(rs.getString("comment_name"));
commentDTO.setComment_comm(rs.getString("comment_comm"));
commentDTO.setSeq(rs.getString("seq"));
return
commentDTO;
}
});
return
list;
}
// 게시글
입력
public int
insertBoard(BoardDTO boardDTO)throws DataAccessException{
String sql = "insert
all"
+ " into board02
values(sequence_board_seq.nextval,name,passwd,title,content,filename,regdate,readcount)"
+ " into reply
values(sequence_board_seq.currval,reply_step,reply_level)"
+ " select ? AS name, ? AS passwd, ? AS
title, ? AS content, ? AS filename,SYSDATE AS regdate, 0 AS
readcount,"
+ " 0 AS reply_step, 0 AS
reply_level"
+ " FROM DUAL";
Object[] obj =
{boardDTO.getName(), boardDTO.getPasswd(),
boardDTO.getTitle(),boardDTO.getContent(), boardDTO.getFilename()};
return
jdbaTemplate.update(sql, obj);
}
}
--------------------------------------------------------------------------------------
4. [BoardService.java] , [BoardServiceImple.java]
package com.board.service;
import java.util.List;
import java.util.Map;
import com.board.model.BoardDTO;
import com.board.model.CommentDTO;
public interface BoardService {
// 게시글 수
public int
boardCount(Map<String, Object>searchMap)throws Exception;
// 게시판 리스트
public
List<BoardDTO> boardList(Map<String, Object>searchMap)throws
Exception;
//게시물 미리보기
public String
preView(String seq)throws Exception;
// 게시글
상세보기
public BoardDTO
readContent(String seq)throws Exception;
// 코멘트 저장
public int
insertComment(CommentDTO commentDTO)throws Exception;
// 코멘트 조회
public
List<CommentDTO> ListComment(String seq)throws Exception;
// 게시글
입력
public int
insertBoard(BoardDTO boardDTO)throws Exception;
}
--------------------------------------------------------------------------------------
package com.board.service;
import java.util.List;
import java.util.Map;
import com.board.dao.BoardDAO;
import com.board.model.BoardDTO;
import com.board.model.CommentDTO;
public class BoardServiceImple implements BoardService {
private BoardDAO
boardDAO;
public void
setBoardDAO(BoardDAO boardDAO){
this.boardDAO =
boardDAO;
}
// 게시글 수
public int
boardCount(Map<String, Object> searchMap) throws Exception {
return
boardDAO.boardCount(searchMap);
}
// 게시판 리스트
public
List<BoardDTO> boardList(Map<String, Object> searchMap) throws
Exception {
return
boardDAO.boardList(searchMap);
}
// 게시물
미리보기
public String
preView(String seq){
return
boardDAO.preView(seq);
}
// 게시글
상세보기
public BoardDTO
readContent(String seq)throws Exception{
return
boardDAO.readContent(seq);
}
// 코멘트 저장
public int
insertComment(CommentDTO commentDTO) throws Exception {
return
boardDAO.insertComment(commentDTO);
}
// 코멘트 조회
public
List<CommentDTO> ListComment(String seq) throws Exception {
return
boardDAO.ListComment(seq);
}
// 게시글
입력
public int
insertBoard(BoardDTO boardDTO)throws Exception{
return
boardDAO.insertBoard(boardDTO);
}
}
5. [BoardMultiController.java]
package
com.onj.board;
import
java.io.FileOutputStream;
import
java.io.IOException;
import
java.util.ArrayList;
import
java.util.HashMap;
import
java.util.List;
import
java.util.Map;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
javax.servlet.http.HttpSession;
import
org.springframework.web.multipart.MultipartFile;
import
org.springframework.web.multipart.MultipartHttpServletRequest;
import
org.springframework.web.servlet.ModelAndView;
import
org.springframework.web.servlet.mvc.multiaction.MultiActionController;
import
com.board.model.BoardDTO;
import
com.board.model.CommentDTO;
import
com.board.service.BoardService;
import
com.board.util.EncodingHandler;
import
com.board.util.PageHandler;
public
class BoardMultiController extends MultiActionController{
private BoardService
boardService;
private PageHandler
pageHandler;
public void
setBoardService(BoardService boardService){this.boardService =
boardService;}
public void
setPageHandler(PageHandler pageHandler){this.pageHandler = pageHandler;}
ModelAndView mav =
null;
// 게시판 리스트
public ModelAndView
list(HttpServletRequest request, HttpServletResponse response)throws
Exception{
mav = new
ModelAndView();
// 상세보기에서 사용한 session
지운다.
HttpSession session =
request.getSession();
if(session.isNew() ==
false){session.invalidate();}
List<BoardDTO> list =
null;
// 검색select , 검색Text
String boardListSelect
= request.getParameter("boardListSelect");
String boardListSearchText
= request.getParameter("boardListSearchText");
Map<String, Object>
searchMap = new HashMap<String, Object>();
if(boardListSearchText !=
null){
searchMap.put("boardListSearchText",
EncodingHandler.toKor(boardListSearchText));
searchMap.put("boardListSelect",
boardListSelect);
mav.addObject("boardListSearchText", EncodingHandler.toKor(boardListSearchText));
mav.addObject("boardListSelect",
boardListSelect);
}
String pageNumber =
request.getParameter("pageNumber");
int pageNum = 1;
if(pageNumber !=
null){pageNum = Integer.parseInt(pageNumber);}
// 게시글 수
int totalCount =
pageHandler.boardAllNumber(searchMap);
// 페이지 갯수
int totalPageCount =
pageHandler.boardPageCount(searchMap);
// startPage ,
endPage
int startPage =
pageHandler.boardStartPage(pageNum);
int endPage =
pageHandler.boardEndPage(pageNum,searchMap);
// 처음, 마지막 rowNumber
List<Object>
rowNumberList = new ArrayList<Object>();
rowNumberList =
pageHandler.boardSetPageNumber(pageNum);
searchMap.put("startRow",
rowNumberList.get(0));
searchMap.put("endRow",
rowNumberList.get(1));
// 글 전체 출력
list =
boardService.boardList(searchMap);
mav.addObject("pageNumber",pageNum);
mav.addObject("boardCount",totalCount);
mav.addObject("totalPageCount",
totalPageCount);
mav.addObject("startPage",
startPage);
mav.addObject("endPage",
endPage);
mav.addObject("list",
list);
mav.setViewName("list");
return mav;
}
// 게시글 상세보기
public ModelAndView
read(HttpServletRequest request, HttpServletResponse response)throws
Exception{
String seq =
request.getParameter("seq");
BoardDTO boardDTO =
boardService.readContent(seq);
// 상세글 내용 session에 담음
HttpSession session =
request.getSession();
session.setAttribute("boardDTO", boardDTO);
mav.addObject("boardDto",
boardDTO);
mav.addObject("comment",
boardService.ListComment(seq));
mav.setViewName("read");
return mav;
}
// 코멘트 저장
public ModelAndView
comment(HttpServletRequest request, HttpServletResponse response)throws
Exception{
HttpSession session =
request.getSession();
BoardDTO boardDTO =
(BoardDTO) session.getAttribute("boardDTO");
mav = new
ModelAndView("redirect:/read.html?seq="+boardDTO.getSeq());
CommentDTO commentDTO = new
CommentDTO();
commentDTO.setComment_name(request.getParameter("comment_name"));
commentDTO.setComment_comm(request.getParameter("comment_comm"));
commentDTO.setSeq(boardDTO.getSeq());
boardService.insertComment(commentDTO);
return mav;
}
// 게시글 입력 화면
public ModelAndView
write(HttpServletRequest request, HttpServletResponse response)throws
Exception{
mav = new
ModelAndView("write");
return mav;
}
// 입력된 글 저장
public ModelAndView writeOk(HttpServletRequest
request ,HttpServletResponse response)throws Exception{
mav = new
ModelAndView("redirect:/list.html");
MultipartHttpServletRequest mpRequest =
(MultipartHttpServletRequest) request;
String name =
request.getParameter("name");
String passwd =
request.getParameter("passwd");
String title =
request.getParameter("title");
String content =
request.getParameter("content");
MultipartFile file =
mpRequest.getFile("file");
// 파일이름
String fileName =
file.getOriginalFilename();
BoardDTO boardDTO = new BoardDTO();
// 파일 저장 위치
String fileDir ="D:/upload/";
byte[] fileData;
FileOutputStream output = null;
if(!fileName.equals("")){
// 파일 저장
try{
fileData = file.getBytes();
output = new
FileOutputStream(fileDir+fileName);
output.write(fileData);
}catch(IOException e){
e.printStackTrace();
}finally{output.close();
}
}else{fileName = " ";}
boardDTO.setName(name);
boardDTO.setPasswd(passwd);
boardDTO.setTitle(title);
boardDTO.setContent(content);
boardDTO.setFilename(fileName);
boardService.insertBoard(boardDTO);
return mav;
}
}
6, [/WEB-INF/jsp/write.jsp] , [css/boardCss.css],
[/js/boardActionJs.js]
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<link rel="stylesheet" type="text/css"
href="/board/css/boardCss.css">
<script type="text/javascript"
src="/board/js/boardActionJs.js"></script>
<meta http-equiv="Content-Type" content="text/html;
charset=EUC-KR">
<title>Insert title here</title>
</head>
<body>
<center>
<h1>오엔제이
프로그래밍 실무교육센터 스프링 게시판</h1><hr>
<form
name="writeForm" method="post" enctype="multipart/form-data">
<table
class="writeTable" border="1" cellpadding="0" cellspacing="0">
<tr>
<td> 제목
</td>
<td><input type="text" name="title"
id="title" size="45"></td>
</tr>
<tr>
<td>작성자
</td>
<td><input type="text" name="name"
id="name" size="45"></td>
</tr>
<tr>
<td>비밀번호
</td>
<td><input type="password" name="passwd"
id="passwd" size="50"></td>
</tr>
<tr>
<td
colspan="2">
<textarea
rows="20" cols="55" name="content" id="content"></textarea>
</td>
</tr>
<tr>
<td>파일</td>
<td>
<input
type="file" name="file" id="file" size="30">
</td>
</tr>
</table>
<table
class="writeTable">
<tr>
<td
colspan="2" id="writeTD">
<input
type="button" value="저장" onclick="writeGoGo();">
<input
type="button" value="취소"
onclick="location.href='/board/list.html';">
</td>
</tr>
</table>
</form>
</center>
</body>
</html>
--------------------------------------------------------------------------------------
@CHARSET "EUC-KR";
td{text-align: center;}
a:link{ text-decoration:none; color: #5D5D5D;}
a:visited{ text-decoration:none; color: #5D5D5D;}
a:active{ text-decoration:none; color: #47C83E;}
a:hover{ text-decoration:none; color: #47C83E;}
.listTable{width:600px;}
#boardListCount{text-align: right;}
#boardList_a{font-weight: bold; color:#8041D9;}
#readTable{width: 600px; height: 200px;}
#readButtonTD{text-align: right;}
.readTD{text-align: left;}
.readTable02{width: 600px;}
.writeTable{width:
400px;}
#writeTD{text-align:
right;}
#layer1{
position:
absolute;
padding:
5px;
filter:
alpha(opacity=50);
width: 250px;
height: 150px;
background-color: white;
border: 2px
#000000 dotted;
visibility:
hidden;
}
--------------------------------------------------------------------------------------
// 검색
function boardListSearchGo(){
document.listForm.action ="/board/list.html";
document.listForm.submit();
}
// 검색Text입력 후 바로 엔터 가능하게 하는 이벤트
function enterEvent(){
if(window.event.keyCode == 13){
boardListSearchGo();
}
}
// 미리보기(Ajax)
var xmlHttp = null;
var xmlDoc = null;
var message = null;
function createXMLHttpRequest(){
// 익스플로러이면 if 그외
브라우저이면 else
if(window.ActiveXObject){
try{
xmlHttp = new
ActiveXObject("Msxml2.XMLHTTP"); // IE 5.0 이하 버전
}catch(e){
try{
xmlHttp = new
ActiveXObject("Microsoft.XMLHTTP"); // IE 5.0 이상 버전
}catch(el){xmlHttp = null;}
}
}else
if(window.XMLHttpRequest){
try{
xmlHttp = new
XMLHttpRequest();
}catch(e){
xmlHttp =
null;
}
}
if(xmlHttp ==
null){errorMessage();}
return
xmlHttp;
}
function errorMessage(){alert("지원할 수 없는 브라우저 입니다.");}
function contentprev(seq){
var url =
"ContentPreview?seq="+seq;
xmlHttp =
createXMLHttpRequest();
xmlHttp.onreadystatechange =
handleStateChange;
xmlHttp.open("get",url,true);
xmlHttp.send(null);
}
function handleStateChange(){
if(xmlHttp.readyState == 4){
if(xmlHttp.status == 200){
xmlDoc =
xmlHttp.responseText;
document.getElementById("layer1").innerHTML =
xmlDoc;
//화면에서 마우스가 움직일때
movetip()함수 발생
document.onmousemove = movetip;
showlayer();
}
}
}
// 게시판 글제목에서 마우스가 올라갔을 경우 발생
function showlayer(){
document.getElementById("layer1").style.visibility="visible";
}
// 게시판 글제목에 마우스가 떨어져 있을 경우 발생
function hidelayer(){
document.getElementById("layer1").style.visibility="hidden";
}
// 미리보기 위치
function movetip(){
document.getElementById("layer1").style.pixelTop =
event.y+document.body.scrollTop+20;
document.getElementById("layer1").style.pixelLeft =
event.x+document.body.scrollLeft+20;
}
// 코멘트 저장
function commentInput(){
var comment_name
= document.getElementById("comment_name");
var comment_comm
= document.getElementById("comment_comm");
if(comment_name.value == ""){
alert("코멘트 이름을
적으세요.");
comment_name.focus();
return
false;
}
if(comment_comm.value == ""){
alert("코멘트 내용을
적으세요.");
comment_comm.focus();
return
false;
}
boardReadForm.action="/board/comment.html";
boardReadForm.submit();
}
//
글입력
function
writeGoGo(){
if(document.writeForm.title.value ==
""){
alert("글 제목을
입력하세요.");
document.writeForm.title.focus();
return false;
}
if(document.writeForm.name.value ==
""){
alert("작성자를
입력하세요.");
document.writeForm.name.focus();
return false;
}
if(document.writeForm.passwd.value ==
""){
alert("비밀번호를
입력하세요.");
document.writeForm.passwd.focus();
return false;
}
if(document.writeForm.content.value ==
""){
alert("글 내용을
입력하세요.");
document.writeForm.content.focus();
return false;
}
writeForm.action="/board/writeOk.html";
writeForm.submit();
}
댓글 없음:
댓글 쓰기