본 내용은 혼자 공부하기 위하여 다른 포스트를 보면서 저에게 필요한 부분과 궁금했던 부분을 추가하여 게시하는 곳입니다.
궁금한 것에 대한 것은 모르는 것이 많겠지만 함께 알아보도록 노력하겠습니다.
참조 게시 포스트 : http://addio3305.tistory.com/
-------------------------------------------------------------------------------------------------------------------------------------------
@CHARSET "UTF-8"; a:link, a:visited {text-decoration: none; color: #656565;} .board_list {width:100%;border-top:2px solid #252525;border-bottom:1px solid #ccc} .board_list thead th:first-child{background-image:none} .board_list thead th {border-bottom:1px solid #ccc;padding:12px 0 13px 0;color:#3b3a3a;vertical-align:middle} .board_list tbody td {border-top:1px solid #ccc;padding:10px 0;text-align:center;vertical-align:middle} .board_list tbody tr:first-child td {border:none} .board_list tbody td.title {text-align:left; padding-left:20px} .board_list tbody td a {display:inline-block} .board_view {width:50%;border-top:2px solid #252525;border-bottom:1px solid #ccc} .board_view tbody th {text-align:left;background:#f7f7f7;color:#3b3a3a} .board_view tbody th.list_tit {font-size:13px;color:#000;letter-spacing:0.1px} .board_view tbody .no_line_b th, .board_view tbody .no_line_b td {border-bottom:none} .board_view tbody th, .board_view tbody td {padding:15px 0 16px 16px;border-bottom:1px solid #ccc} .board_view tbody td.view_text {border-top:1px solid #ccc; border-bottom:1px solid #ccc;padding:45px 18px 45px 18px} .board_view tbody th.th_file {padding:0 0 0 15px; vertical-align:middle} .wdp_90 {width:90%} .btn {border-radius:3px;padding:5px 11px;color:#fff !important; display:inline-block; background-color:#6b9ab8; border:1px solid #56819d;vertical-align:middle}
포스트에서 그대로 가져온 디자인으로 간단한 디자인이다. 작성자는 디자인의 디자도 몰라서 이렇게 그대로 가져왔다.
1.2 자바스크립트 공통함수
- src/main/webapp/js 경로에 common.js라는 javascript 파일을 하단과 같이 작성하자
function gfn_isNull(str) { if (str == null) return true; if (str == "NaN") return true; if (new String(str).valueOf() == "undefined") return true; var chkStr = new String(str); if( chkStr.valueOf() == "undefined" ) return true; if (chkStr == null) return true; if (chkStr.toString().length == 0 ) return true; return false; } function ComSubmit(opt_formId) { this.formId = gfn_isNull(opt_formId) == true ? "commonForm" : opt_formId; this.url = ""; if(this.formId == "commonForm"){ $("#commonForm")[0].reset(); } this.setUrl = function setUrl(url){ this.url = url; }; this.addParam = function addParam(key, value){ $("#"+this.formId).append($("<input type='hidden' name='"+key+"' id='"+key+"' value='"+value+"' >")); }; this.submit = function submit(){ var frm = $("#"+this.formId)[0]; frm.action = this.url; frm.method = "post"; frm.submit(); }; }
- 첫번째는 널(null) 체크하는 함수이다.
- 두번째인 submit 기능을 하는 함수이다. 보통 전송기능인 submit은 form과 <input type="submit"> 을 많이 사용한다.
그렇지만 이는 파라미터의 동적 추가나 공통적인 파라미터 추가, 아무것도 없을 때의 화면이동이 불편한 경우가 많다. 따라서 숨겨둔 form을 하나 만들어놓고,그 폼을 이용하여 페이지의 이동 및 입력 값 전송을 하려고 한다.
1.3 공통 포함 파일 작성
위의 CSS파일과 js 파일은 공통으로 jsp파일들에 들어가기 때문에 한 파일에 선언하고 그 파일을 include하여 관리하기 편하게 만들 것이다.
- src/main/webapp/WEB-INF/include 경로에 include-header.jspf, include-body.jspf을 만들고 하단과 같이 작성한다.
include-header.jspf
<%@ page pageEncoding="utf-8"%> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> <link rel="stylesheet" type="text/css" href="<c:url value='/css/ui.css'/>" /> <!-- jQuery --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> <script src="<c:url value='/js/common.js'/>" charset="utf-8"></script>
include-body.jspf
<%@ page pageEncoding="utf-8"%> <form id="commonForm" name="commonForm"></form>
- header 파일에선 메타정보, 스타일 시트, 태그 라이브러리, 스크립트 등 화면 호출이 완료 되기 전 가져와야 될 것들을 선언하였다.
- body 파일에선 여기서는 위에서 작성한 common.js에 있는 submit 기능을 위한 숨김 폼 하나만 넣어뒀다.
2. 게시글 쓰기 페이지
게시글 리스트 페이지와 동일하게 Controller -> Service -> ServiceImpl -> DAO -> SQL -> jsp 순으로 작성할 것이다.
2.1 Controller
@RequestMapping(value="/sample/openBoardWrite.do") public ModelAndView openBoardWrite(CommandMap commandMap) throws Exception{ ModelAndView mv = new ModelAndView("/sample/boardWrite"); return mv; } @RequestMapping(value="/sample/writeBoard.do") public ModelAndView writeBoard(CommandMap commandMap) throws Exception{ ModelAndView mv = new ModelAndView("redirect:/sample/openBoardList.do"); sampleService.writeBoard(commandMap.getMap()); return mv; }
SampleController.java에 위 부분을 추가한다.
- 1~6줄
이 메서드는 게시글 쓰기 페이지 자체를 매핑하여 잡아주는 메서드로 크게 특별한 점은 없고 boardWrite라는 jsp 파일로 뷰 페이지로 이동한다.
- 8~14줄
이 메서드는 게시글 쓰기 페이지에서 게시글을 작성한 뒤 등록하기 버튼을 눌렀을 경우의 클라이언트 요청을 매핑하는 메서드로 10줄의 경우는 해당 작업을 완료하고 돌아갈 위치로 게시글 보기 페이지로 돌아간다는 것을 뜻한다.
11줄은 sampleService의 writeBoard 메서드에 CommandMap 안에 있는 Map을 보내주는 데 이 Map 안에는 제목과 내용의 값들이 들어있을 예정이다.
2.2 Service와 ServiceImpl
SampleService.java
void writeBoard(Map<String,Object> map) throws Exception;
SampleServiceImpl.java
public void writeBoard(Map<String, Object> map) throws Exception { sampleDAO.writeBoard(map); }
Service와 ServiceImpl 부분에 해당 코드들을 추가 시켜준다.
- 이 코드들은 아까 controller 부분에서 호출했던 메서드로 게시글 작성을 완료하고 등록하기 버튼을 눌렀을 때의 처리하는 부분으로 DAO의 메서드를 부르고 마찬가지로 map을 넘겨준다.
2.3 DAO
SampleDAO.java
public void writeBoard(Map<String,Object> map) { insert("sample.writeBoard", map); }
SampleDAO 부분에도 해당 코드들을 추가한다.
- 이 코드도 위와 마찬가지이며 지난번 작성하였던 상속받은 CommonDAO의 메서드인 insert를 활용하여 앞에 "SQL.ID값",파라미터를 sqlSession을 사용하여 SQL문을 DB에 보내준다.
2.4 SQL
sample_SQL.xml
<insert id="sample.writeBoard" parameterType="hashmap"> <![CDATA[ INSERT INTO TB_BOARD1( TITLE, CONTENTS, HIT_CNT, DEL_GB, CREA_ID) VALUES( #{TITLE}, #{CONTENTS}, 0, 'N', 'ADMIN') ]]> </insert>
위에서 DB로 보내주는 SQL문으로 파라미터에 포함되어 있던 TITLE, CONTENTS가 #{TITLE}, #{CONTENTS}라고 쓰인 것이 보인다. Mybatis에서는 변수 대입을 #{변수명}으로 사용한다. 여기서 TITLE, CONTENTS는 다음에 살펴볼 jsp 페이지에서 태그에 name에 해당하는 값이다. 즉 어떤 태그에 name="TITLE"이라고 쓰였던 것이다.
2.5 JSP
마지막으로 살펴볼 JSP 페이지이다.
boardWrite.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>글쓰기</title> <%@ include file="/WEB-INF/include/include-header.jspf" %> </head> <body> <form id="frm"> <table class="board_view"> <colgroup> <col width="15%" > <col width="*" > </colgroup> <caption>게시글 작성</caption> <tbody> <tr> <th scope="row">제목</th> <td><input type="text" name="TITLE" class="wdp_90" /></td> </tr> <tr> <th scope="row">내용</th> <td><textarea cols="100" rows="20" id="CONTENTS" name="CONTENTS" title="내용"></textarea></td> </tr> </tbody> </table> <a href="#this" id="list" class="btn">목록으로</a> <a href="#this" id="write" class="btn">글쓰기</a> </form> <%@ include file="/WEB-INF/include/include-body.jspf" %> <script type="text/javascript"> $(document).ready(function(){ $("#list").on("click",function(e){ e.preventDefault(); fn_openBoardList(); }) $("#write").on("click",function(e){ e.preventDefault(); fn_writeBoard(); }) }); function fn_openBoardList(){ var comSubmit = new ComSubmit(); comSubmit.setUrl("<c:url value='/sample/openBoardList.do'/>"); comSubmit.submit(); } function fn_writeBoard(){ var comSubmit = new ComSubmit("frm"); comSubmit.setUrl("<c:url value='/sample/writeBoard.do'/>"); comSubmit.submit(); } </script> </body> </html>
- 특별한 것들만 꼽자면 8줄,33줄의 include의 경우 아까 공통적으로 들어가는 부분이여서 따로 작성하여 준 부분이다.
- 21,25줄을 보면 방금 전 말했듯이 태그 안에 name 속성이 TITLE, CONTENTS인 것을 볼 수 있다. 이 부분을 myBatis에서 #{변수명}으로 사용한 것이다. 이 부분이 어떻게 Controller의 파라미터를 통해서 들어갔는 지에 대해서는 밑에서 설명하겠다.
- 48~52줄
var comSubmit = new ComSubmit(); 부분은 자바스크립트 객체를 생성하는 부분이다.
우리가 자바에서 객체를 생성할 때와 비슷한 방식임을 알 수 있다. 위에서 common.js 에 submit 기능을 하는 함수를 만들었는데, 그것이 ComSubmit 객체이다. 그 다음으로 ComSubmit 객체 내의 setUrl 함수를 이용하여 호출하고 싶은 주소를 입력하도록 하였다. 여기서 <c:url> 태그는 JSTL 태그로, 이 태그를 이용하여 ContextPath를 자동으로 붙이도록 하였다. 만약 JSTL을 이용하지 않는다면, comSubmit.setUrl("/first/sample/openBoardList.do"); 라고 작성하면 된다. 그렇지만 <c:url> 태그를 이용하기를 권장한다. 마지막으로 ComSubmit 객체의 submit 함수를 이용하여 전송(submit)을 하였다. 많은 사람들이 폼(form)을 이용하여 전송을 할때는 다음과 같이 폼을 만든다.
<form id="frm" name="frm" method="post" action="/first/sample/openBoardList.do"></form>
그 후, <input type="submit" value="전송"/>와 같은 태그를 이용하여 전송(submit)을 한다. 그렇지만 이 경우, 폼을 만들 필요가 없는 부분에서도 폼을 만들거나, 동일한 내용을 반복해서 작성해야 하는 불편함이 있다.
- 54~58줄
"목록으로" 버튼과 비슷하다. 차이점은 ComSubmit 객체를 생성할 때 form의 아이디인 frm을 인자값으로 넘겨주었다.
ComSubmit 객체는 객체가 생성될 때, 폼의 아이디가 인자값으로 들어오면 그 폼을 전송하고, 파라미터가 없으면 숨겨둔 폼을 이용하여 데이터를 전송하도록 구현하였다. 따라서 전송할 데이터가 있는 frm이라는 id를 가진 form을 이용하도록 id를 넘겨주었다. 이 때 위에서 말했던 TITLE, CONTENTS가 전송되는 것이다.
2.6 확인하기
- 주소창에 localhost:8080/myapp/openBoardWrite.do 를 입력하여 창이 잘 열리는 지 확인하자.
- 그리고 밑과 같이 내용을 입력하고 글쓰기를 눌러보자.
- 위처럼 뜬다면 잘 따라왔다는 것이다.
- 그리고 이클립스의 콘솔창을 보자.
- SQL문과 URI등 여러 결과 값 로그들이 찍혀있는 것이 보일 것이다. 잘 살펴보면 START와 END로 구분되어진 것이 보이는데 START에서 END까지가 하나의 호출로 맨 위의 경우는 글쓰기 페이지의 호출, 그 뒤로는 작성하기 버튼을 눌렀을 때의 호출, 그리고 마지막으로는 게시글 리스트 보기 페이지에 대한 호출, 총 3개의 호출이 보인다.
'코딩 > Spring' 카테고리의 다른 글
Spring 개발 - 게시판 만들기(12) - 게시글 수정하기, 삭제하기 (1) | 2017.12.26 |
---|---|
Spring 개발 - 게시판 만들기(11) - 게시글 상세보기 (0) | 2017.12.26 |
Spring 개발 - 게시판 만들기(9) - HandlerMethodArgumentResolver 적용 (0) | 2017.12.25 |
Spring 개발 - 게시판 만들기(8) - 게시판 목록 만들기 (0) | 2017.12.24 |
Spring 개발 - 게시판 만들기(7) - Mybatis 연동하기 (0) | 2017.12.24 |