Spring 게시판구현 1 차버젂최종본 오라클자바커뮤니티에서설립한오엔제이프로그래밍실무교육센터 ( 오라클 SQL, 튜닝, 힌트, 자바프레임워크, 안드로이드, 아이폰, 닷넷실무전문강의 ) www.onjprogramming.co.kr 1. 구현된기능 - 게시판리스트보기 + 게시물본문내용미리보기 + 게시글상세보기 + 커멘트 ( 댓글 ) 기 능 + 글쓰기 + 글수정하기 + 글삭제하기 + 답변글 2. DAO 쪽클래스 [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; // 답글달기 public int replyboard(boarddto board) 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"; /* * reply : 답변인경우어느글의답변인지상위글번호 * 최상위글인경우 reply 는자신의글번호 (seq) 와동일, 리스트보기에서정령시우선 reply 로우선하게된다.
두답변은 reply_level 이같다. 들여쓰기를핚다. * reply_level : 1 차, 2 차답글인지여부, 하나의글에답변이두개면그 * list.jsp 에서글을뿌릴때 reply_level 에따라 * reply_step : 하나의글아래에생기는모든답변들에대해순차적으로 1 씩증가, reply_level 과관계없이 */ String sql = " select * from (select seq, name, passwd, " + " title, content, filename, regdate, " + " readcount, reply, reply_step, " + " reply_level, rownum r " + " from board " + " order by reply desc, reply_step asc)"; 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 =?"; rownum) String precontent = (String) jdbctemplate.queryforobject(sql, new Object[] { seq, new RowMapper() { public Object maprow(resultset rs, int ); return precontent; throws SQLException { return rs.getstring("content");
// 게시판상세보기, 게시글읽기 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.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.setseq(rs.getint("seq")); board.setname(rs.getstring("name")); board.setreadcount(rs.getint("readcount")); board.setreply(rs.getint("reply")); board.setreply_step(rs.getint("reply_step")); board.setreply_level(rs.getint("reply_level")); ); // 글조회수 1 증가 this.updatereadcount(new Integer(boardDTO.getSeq()).toString()); return board; 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 =?"; rownum) CommentDTO(); List<CommentDTO> commentlist = jdbctemplate.query(sql, new Object[] { seq, new RowMapper() { public Object maprow(resultset rs, int commentdto.setname(rs.getstring("name")); commentdto.setcomment(rs.getstring("comm")); throws SQLException { CommentDTO commentdto = new ); return commentlist; return commentdto; // 글쓰기 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 { seq =?"; String sql = "update board set title =?, content =? where 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; { // 답글달기 public int replyboard(boarddto boarddto) throws DataAccessException int result = 0; String name = boarddto.getname(); String passwd = boarddto.getpasswd(); String title = boarddto.gettitle(); String content = boarddto.getcontent(); String filename = boarddto.getfilename(); int reply = boarddto.getreply(); int reply_step = boarddto.getreply_step(); int reply_level = boarddto.getreply_level(); // 현재답변을단게시물보다더높은스텝의게시물이있다면스텝을하나씩 상승시킴 String sql1 = "update board set reply_step = reply_step + 1 " + "where reply = " + reply + " and reply_step > " + reply_step; jdbctemplate.update(sql1); String sql2 = "insert into board values(board_seq.nextval,?,?,?,?,?, sysdate, 0,?,?,?)"; // reply_step 과 reply_level 을 1 씩증가시킨후내용을저장 Object[] obj2 = { name, passwd, title, content, filename, reply, reply_step + 1, reply_level + 1 ; result = jdbctemplate.update(sql2, obj2); return 0; 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); // 답글등록 public int replyboard(boarddto board); [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); // 답글등록 public int replyboard(boarddto board){ return boarddao.replyboard(board);
[BoardServiceHelper.java] package onj.board.service; import javax.servlet.servletcontext; import org.springframework.web.context.webapplicationcontext; import org.springframework.web.context.support.webapplicationcontextutils; public class BoardServiceHelper { public static BoardService getboardservice(servletcontext ctx) { WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(ctx); //boardconfig.xml 에정의된 boardservice 빈을리턴 // 이부분은게시물미리보기서블릿 (ContentPreview) 에서스프링의인스턴 스를얻을때이용 return (BoardService) wac.getbean("boardservice"); 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");
Exception { // 게시물상세보기에서답변클릭시호출되어답변달 reply.jsp 로연결 public ModelAndView reply(httpservletrequest req, HttpServletResponse res) throws String seq = req.getparameter("seq"); // 답변달게시물내용을 reply.jsp 넘긴다. ModelAndView mav = new ModelAndView("reply", //view이름 "reply", //readcontent가넘기는 boarddto의이름, reply.jsp에서사용 boardservice.readcontent(seq)); return mav; // 답글저장 public ModelAndView replyok(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"); String filename = ""; String reply = req.getparameter("reply"); String reply_step = req.getparameter("reply_step"); String reply_level = req.getparameter("reply_level"); BoardDTO boarddto = new BoardDTO(name, passwd, title, content, filename); boarddto.setseq(integer.parseint(seq)); boarddto.setreply(integer.parseint(reply)); boarddto.setreply_level(integer.parseint(reply_level)); boarddto.setreply_step(integer.parseint(reply_step)); boardservice.replyboard(boarddto);
return new ModelAndView("redirect:/list.html"); 5. AJAX 에서이용되는게시물미리보기서블릿 [ContentPreview.java] package onj.board.ajaxpreview; import java.io.ioexception; import java.io.printwriter; import javax.servlet.servletexception; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import onj.board.service.boardservice; import onj.board.service.boardservicehelper; //Servlet3.0이상, Tomcat7 이상에서는애노테이션으로서블릿정의가가능하다. //@WebServlet(urlPatterns = "/preview") public class ContentPreview extends HttpServlet { protected void doget(httpservletrequest req, HttpServletResponse res) throws ServletException, IOException { String seq = req.getparameter("seq"); req.setcharacterencoding("utf-8"); res.setcontenttype("text/html; charset=utf-8"); res.setheader("cache-control", "no-cache"); BoardService boardservice = BoardServiceHelper.getBoardService(getServletContext()); PrintWriter out = res.getwriter(); out.println("<pre>" + boardservice.preview(seq) + "<pre>");
6. model 쪽클래스 [BoardDTO.java] package onj.board.model; public class BoardDTO { private int seq; private String name; private String passwd; private String title; private String content; private String filename; private String regdate; private int readcount; private int reply; private int reply_step; private int reply_level; public BoardDTO() { public BoardDTO(String name, String passwd, String title, String content, String filename) { this.name = name; this.passwd = passwd; this.title = title; this.content = content; this.filename = filename; public BoardDTO(String name, String passwd, String title, String content, String filename, int readcount) { this.name = name; this.passwd = passwd; this.title = title; this.content = content; this.filename = filename; this.readcount = readcount; 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 getpasswd() { return passwd; public void setpasswd(string passwd) { this.passwd = passwd; public String gettitle() { return title; public void settitle(string title) { this.title = title; public String getcontent() { return content; public void setcontent(string content) { this.content = content; public String getfilename() { return filename; public void setfilename(string filename) { this.filename = filename; public String getregdate() { return regdate.substring(0, 10); //2013-07-15 형태 public void setregdate(string regdate) { this.regdate = regdate; public int getreadcount() { return readcount; public void setreadcount(int readcount) { this.readcount = readcount; public int getreply() { return reply;
public void setreply(int reply) { this.reply = reply; public int getreply_step() { return reply_step; public void setreply_step(int reply_step) { this.reply_step = reply_step; public int getreply_level() { return reply_level; public void setreply_level(int reply_level) { this.reply_level = reply_level; [commentdto.java] package onj.board.model; public class CommentDTO { public String seq; public String name; // 게시글번호 // 이름 public String comment;// 커맨트 public CommentDTO() { public String getseq() { return seq; public void setseq(string 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;
7. /jsp/list.jsp [list.jsp] <%@ page contenttype="text/html; charset=euc-kr" language="java" errorpage="" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title> 오엔제이프로그래밍실무학원 </title> <meta http-equiv="content-type" content="text/html; charset=euc-kr"> <style type="text/css"> #layer1{ position:absolute; padding:5px; filter:alpha(opacity=50); width:250px; height:150px; background-color:white; border:2px #000000 dotted; visibility:hidden; </style> <script language="javascript" type="text/javascript" src="/onjboard1/js/createxmlhttprequest.js"></script> <script type="text/javascript"> var xmlhttp; var xmldoc; var message; function contentprev(seq){ var url = "preview?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; function showlayer(id){ if(document.all)
document.all[id].style.visibility="visible"; else if(document.layers) document.layers[id].style.visibility="visible"; function hidelayer(id){ if(document.all) document.all[id].style.visibility="hidden"; else if(document.layers) document.layers[id].style.visibility="hidden"; function movetip() { layer1.style.pixeltop=event.y+document.body.scrolltop+10; layer1.style.pixelleft=event.x+document.body.scrollleft+10; document.onmousemove=movetip; </script> </head> <body> <div id="layer1"> 게시물본문미리보기 </div> <div style="width:500px;"> <div style="float:right;"> <H3> 오엔제이프로그래밍실무교육센터스프링게시판 </H3> <h5> 총 ${list.size() 건 </h5> <table width="600" border="1" align="left"> <tr align="left"> <td width="10%" align="center"> 번호 </td> <td width="40%" align="center"> 제목 </td> <td width="20%" align="center"> 이름 </td> <td width="20%" align="center"> 날짜 </td> <td width="10%" align="center"> 조회 </td> <!-- list를가져와서 board라명명후개수만큼반복 --> <c:foreach var="board" items="${list"> <td align="center"> <c:if test="${board.reply_step == 0"> ${board.seq </c:if> <c:if test="${board.reply_step!= 0"> </c:if> </td> <td> <!-- 게시물은덧글에따른번호와덧글존재유무로정렧됨 --> <c:choose> <c:when test="${board.reply_step!= 0"><!-- 게시글이덧글일경우 --> <c:foreach var="i" begin="1" end="${board.reply_level" step="1"><!-- 레벨의수만큼글을뒤로민다 --> </c:foreach> <a
href="read.html?seq=${board.seq" onmouseover="contentprev('${board.seq');showlayer('layer1');" onmouseout="hidelayer('layer1');">${board.title</a> <!-- 마우스를올리면게시물번호에따른 showlayer( 게시물미리보기창 ) 가실행됨 --> </c:when> <c:when test="${board.reply_step == 0"> <a href="read.html?seq=${board.seq" onmouseover="contentprev('${board.seq');showlayer('layer1');" onmouseout="hidelayer('layer1');">${board.title</a> </c:when> </c:choose> </td> <td align="center">${board.name</td> <td align="center">${board.regdate</td> <td align="center">${board.readcount</td> </c:foreach> <td align="center"><input type="button" value=" 글쓰기 " onclick="location.href='/onjboard1/jsp/write.jsp'"></td> <td> </td> <td> </td> <td> </td> <td> </td> </table> </div> </div> </body> </html> 8. 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(){
</script> </head> document.viewform.action = '/onjboard1/update.html'; document.viewform.submit(); <body> <div style="width:600px;"> <div style="float:enter;"> <table width="600" height="420" border="1" align="center"> <tr height="20"><h2> 오엔제이프로그래밍실무교육센터게시판 </h2> <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"> <td width="100">* 이름 </td> <td width="500">: <input name="name" type="text" value="${read.name" size="50" readonly> </td> <td>* 제목 </td> <td>: <input name="title" type="text" value="${read.title" size="50" ></td> <tr align="center"> <td colspan="2"><textarea name="content" cols="80" rows="12" >${read.content</textarea></td> <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> <td> </td> <td><input name="button" type="button" onclick="location.href='/onjboard1/reply.html?seq=${read.seq'" value=" 답변 "> <input name="button" type="button" onclick="update_ok()" value=" 수정 "> <input name="button" type="button" onclick="location.href='/onjboard1/jsp/delete.jsp?seq=${read.seq'" value=" 삭제 ">
<input name="button" type="button" onclick="location.href='/onjboard1/list.html'" value=" 목록 "></td> </form> <td height="99" colspan="2"> <!-- BoardMultiController 의 comment() 메소드호출 --> <form method="post" action="comment.html"> <table border="1"> <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> </table> <input type="hidden" name="seq" value="${read.seq"> </form> <!-- 달려있는커맨트보기 --> <table width="789" border="1"> <c:foreach var="comment" items="${comments"> <td width="42" align="center">*</td> <td width="86">${comment.name</td> <td width="639">${comment.comment</td> </c:foreach> </table> </td> </table> <br><br> <table><td><b>http://www.onjprogramming.co.kr</td></table > </div> </div> </body> </html> 9. /jsp/reply.jsp 작성. [reply.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 write_ok(){ if(document.form.name.value == ""){ alert(" 이름을입력하세요."); document.form.name.focus(); return false; if(document.form.title.value == ""){ alert(" 제목을입력하세요."); document.form.title.focus(); return false; if(document.form.content.value == ""){ alert(" 내용을입력하세요."); document.form.content.focus(); return false; if(document.form.passwd.value == ""){ alert(" 비밀번호를입력하세요."); document.form.passwd.focus(); return false; form.submit(); </script> </head> <body> <div style="width:600px;"> <form method="post" name="form" action="/onjboard1/replyok.html"> <table><td><h2> 오엔제이프로그래밍실무교육센터 게시판 ( 답글달기 )</h2><td></table> <table width="600" height="277" border="1" align="center"> <td width="120">* 이름 </td> <td width="480">: <input name="name" type="text" size="50"></td> <td>* 제목 </td> <td>: <input name="title" type="text" value="re: ${reply.title" size="50"></td> <tr align="center"> <td colspan="2"><textarea name="content" cols="80" rows="10">${reply.content</textarea></td> <td>* 비밀번호 </td> <td>: <input type="password" name="passwd"></td>
<td> </td> <td><input type="button" value=" 답변 " onclick="write_ok();"> <input type="button" value=" 취소 " onclick="history.back();"></td> </table> <input type="hidden" name="seq" value="${reply.seq"> <input type="hidden" name="reply" value="${reply.reply"> <input type="hidden" name="reply_step" value="${reply.reply_step"> <input type="hidden" name="reply_level" value="${reply.reply_level"> </form> </div> <br><br> <table><td><b>http://www.onjprogramming.co.kr</td></table > </body> </html> 10. /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; </script> </head> delform.submit(); <body> <form method="post" name="delform" action="/onjboard1/delete.html"> <table border="1" align="center"> <td> 비밀번호 </td> <td><input type="text" name="passwd"></td> <td><input type="button" value=" 확인 " onclick="del_ok();"> <input name="button" type="button" value=" 취소 " onclick="history.back();"></td>
</table> <table align="center"><td><a href="/onjboard1/list.html"> 목록보기 </a></td></table> <input type="hidden" name="seq" value="${param.seq"> </form> </body> </html> 11. /jsp/write.jsp 작성. [write.jsp] <%@ page contenttype="text/html; charset=euc-kr" language="java" errorpage="" %> <!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 language="javascript" type="text/javascript"> function form_check(){ if(document.form.name.value == ""){ alert(" 이름을입력하세요."); document.form.name.focus(); return false; if(document.form.title.value == ""){ alert(" 제목을입력하세요."); document.form.title.focus(); return false; if(document.form.content.value == ""){ alert(" 내용을입력하세요."); document.form.content.focus(); return false; if(document.form.passwd.value == ""){ document.form.submit(); function addfileform(){ alert(" 비밀번호를입력하세요."); document.form.passwd.focus(); return false; var tb1 = document.getelementbyid("file_table"); if(9 >= tb1.rows.length) { var idx = getobj().parentelement.rowindex + 1; var trow= tb1.insertrow(idx);
var uploadobj="<input name='attatch' type='file' class='text_form' id='f_id'><a OnClick='javascript:addFileForm();'> 추가 </a> <a OnClick='javascript:deleteRow();'> 삭제 </a> "; trow.insertcell(0).innerhtml = uploadobj; else { alert(" 문서파일은 10 개이상접수핛수없습니다."); return; function getobj() { var obj = event.srcelement while (obj.tagname!='td') //TD 가나올때까지의 Object 추출 { obj = obj.parentelement return obj function deleterow(){ var tb1 = document.getelementbyid("file_table"); var idx = getobj().parentelement.rowindex; if(tb1.rows.length-1!=0){ var trow = tb1.deleterow(idx); else{ document.getelementbyid('f_id').select(); document.selection.clear(); </script> </head> <body> <H3> 오엔제이프로그래밍실무교육센터스프링게시판글쓰기 </H3> <div style="width:600px;"> <div style="float:right;"> <!-- /write.html 요천의경우컨트롤로의 write 메소드가실행되도록매핑되어있다 --> <form name="form" method="post" action="/onjboard1/write.html" enctype="multipart/form-data"> <table width="580" height="277" border="1" align="center"> <td width="100">* 이름 </td> <td width="580">: <input name="name" type="text" size="50"> </td> <td>* 제목 </td> <td>: <input name="title" type="text" size="50"></td> <tr align="center">
<td colspan="2"><textarea name="content" cols="80" rows="10"></textarea></td> <td>* 파일 :</td> <td><table id="file_table"> <td> type="file" class="text_form" id="f_id"><a <input name="attatch" OnClick="javascript:addFileForm();"> 추가 </a> <a OnClick="javascript:deleteRow();"> 삭제 </a> </td> </table> </td> <td>* 비밀번호 </td> <td>: <input type="password" name="passwd"></td> <td> </td> <td><input type="button" name="submit" value=" 쓰기 " onclick="form_check();"> <input type="button" name="submit2" value=" 취소 " onclick="history.back();"></td> </table> </div> </div> </form> </body> </html> 12. /js/createxmlhttprequest.js. [createxmlhttprequest.js] function createxmlhttprequest(){ var xmlhttp; if(window.activexobject){ try{ ActiveXObject("Msxml2.XMLHTTP"); ActiveXObject("Microsoft.XMLHTTP"); catch(e){ try{ xmlhttp = new xmlhttp = new catch(e1){ xmlhttp = null;
else if(window.xmlhttprequest){ try{ xmlhttp = new XMLHttpRequest(); catch(e){ xmlhttp = null; if(xmlhttp == null) errormessage(); return xmlhttp; function errormessage(){ alert(" 지원핛수없는브라우저입니다."); 13. /WEB-INF/action-servlet.xml [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.propertiesmet hodnameresolver"> <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> <!-- reply.html 요청이오면컨트롤러의 reply 메소드 <prop key="/reply.html">reply</prop> <!-- replyok.html 요청이오면컨트롤러의 replyok 메소드실행 --> <prop key="/replyok.html">replyok</prop> </props> </property> </bean> <!-- 뷰리졸버 --> <bean id="viewresolver" class="org.springframework.web.servlet.view.internalresourceviewreso lver"> <property name="prefix"> <value>/jsp/</value> </property> <property name="suffix"> <value>.jsp</value>
</beans> </property> </bean> <!-- 컨트롤러매핑 --> <bean name="/list.html /read.html /comment.html /write.html /update.html /delete.html /reply.html /replyok.html" class="onj.board.controller.boardmulticontroller"> <property name="methodnameresolver"> <ref local="usercontrollermethodnameresolver" /> </property> <property name="boardservice"> <ref bean="boardservice" /> </property> </bean> 14. /WEB-INF/boardConfig.xml [boardconfig.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="boarddao" class="onj.board.dao.springboarddao"> <property name="datasource"> <ref bean="datasource"/> </property> </bean> <bean id="boardservice" class="onj.board.service.boardserviceimpl"> <property name="boarddao"> <ref bean="boarddao"/> </property> </bean> </beans> 15. /WEB-INF/web.xml [web.xml] <?xml version="1.0" encoding="utf-8"?> <web-app id="webapp_id" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>onjspringboard1.0, 오엔제이프로그래밍실무교육센터 </displayname> <filter> <filter-name>encodingfilter</filter-name> <filterclass>org.springframework.web.filter.characterencodingfilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>euc-kr</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingfilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- ContextLoaderListener 설정 --> <listener> <listener-class> org.springframework.web.context.contextloaderlistener </listener-class> </listener> <!-- ContextLoaderListener 설정파일 --> <context-param> <param-name>contextconfiglocation</param-name> <param-value> /WEB-INF/boardConfig.xml, /WEB-INF/action-servlet.xml </param-value> </context-param> <!-- 디스패처서블릿정의설정 --> <servlet> <servlet-name>action</servlet-name> <servletclass>org.springframework.web.servlet.dispatcherservlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping> <!-- 게시물미리보기기능을위핚 ajax 처리용서블릿정의 --> <servlet> <servlet-name>preview</servlet-name> <servlet-class>onj.board.ajaxpreview.contentpreview</servletclass> </servlet>
</web-app> <servlet-mapping> <servlet-name>preview</servlet-name> <url-pattern>/preview</url-pattern> </servlet-mapping>