상세 컨텐츠

본문 제목

Spring 블로그 만들기 - 6.수정 및 삭제

개발/Spring 블로그 만들기

by 똘똘이박사 2019. 2. 20. 05:23

본문



이 포스팅의 샘플 게시판 개발 환경은 MAC OS, STS, OpenJDK11 입니다.



게시판 수정 및 삭제는 아래와 같은 순서로 진행 합니다.

  1. 상세내용 조회에 [수정] 버튼 이벤트 추가

  2. Constroller 수정 (게시글 수정)

  3. 입력 화면의 수정

  4. 데이터 저장을 위한 Controller 수정

  5. 상세내용 조회에 [삭제] 버튼 이벤트 추가

  6. Service 수정 (게시글 삭제)

  7. Controller 수정 (게시글 삭제)



블로그 만들기 - 6. 수정 및 삭제


게시물의 수정 화면은 기존에 만들었던 입력 폼을 수정하여 진행할 예정입니다.

따라서 입력 폼에 대한 수정과 함께 많은 부분에서 변화를 줄 예정입니다.

우선 이전 포스팅에서 버튼만 만들고 이벤트를 처리하지 않았던 [수정] 버튼의 이벤트 처리 부터 시작해 봅니다.


상세내용 조회에 [수정] 이벤트 추가 하기

아래의 코드를 boardContent.jsp 의 스크립트 부분(<script></script>)에 추가 합니다.


boardContent.jsp

<script>

//목록으로 이동 이벤트

$(document).on('click', '#btnList', function(){

location.href = "${pageContext.request.contextPath}/board/getBoardList";

});

//수정 버튼 클릭 이벤트

$(document).on('click', '#btnUpdate', function(){

var url = "${pageContext.request.contextPath}/board/editForm";

url = url + "?bid="+${boardContent.bid};

url = url + "&mode=edit";


location.href = url;

});

</script>


위 코드에 보면 수정 페이지로 이동 할 때 두 가지 인자값을 가지고 이동하는 것을 알 수 있습니다.

글번호(bid)는 어떤 글을 편집 할 지 알아야 하기 때문에 필요한 인자 입니다.

mode 인자는, 우리가 입력 폼을 신규 입력 이외에 수정에서도 같이 사용 하기로 했기 때문에 필요한 인자 입니다.

신규 입력과 수정 간의 차이를 구분하기 위해 사용할 인자값 입니다. 

(물론 bid 값의 유무에 따라 신규와 수정을 구분 할 수 있긴 하지만, 

샘플 게시판에서는 명확히 구분할 수 있는 구분값을 가지고 처리 하겠습니다.)



Controller 수정 (게시글 수정)

게시글 수정의 경우 서버에서 할 일은 수정할 데이터를 읽어와 수정 페이지로 넘기기 때문에

Service를 별도로 만들 필요가 없습니다.

이전에 상세내용조회에서 사용했던 Service(getBoardContent() 메소드)를 재사용 하면 됩니다. 

따라서 아래와 같이 바로 Controller를 수정합니다.


BoardController.java 추가내용

@RequestMapping(value = "/editForm", method = RequestMethod.GET)

public String editForm(@RequestParam("bid") int bid

@RequestParam("mode") String mode, Model model) throws Exception {

model.addAttribute("boardContent", boardService.getBoardContent(bid));

model.addAttribute("mode", mode);

model.addAttribute("boardVO", new BoardVO());

return "board/boardForm";

}


여기에 새롭게 추가된 녀석이 있는데 model.addAttribute("boardVO", new BoardVO()); 부분입니다.

이 구문은 바로 아래 입력 폼의 수정을 위해 사용하게 되는데 입력폼과 연계 하기 위해서 입니다.



입력 화면의 수정

앞서 이야기 했듯이 수정 화면은 기존에 만들었던 입력 화면을 수정하여 사용합니다.

가장 큰 변화는 기존의 HTML FORM 태그를 사용하지 않고 <form:form></form:form> 태그를 사용한다는 것입니다.

스프링 버전 2.0 부터 지원되기 시작한 <form:form> 태그는 

데이터바인딩과 관련된 여러 가지 태그를 사용 할 수 있다는  이점이 있습니다.

<form:form> 태그를 사용하기 위해서는 우선 태그라이브러리를 추가해야 합니다.

입력폼(boardForm.jsp) 상단에 아래와 같이 추가 합니다.


<%@ taglib prefix="form" uri = "http://www.springframework.org/tags/form" %> 


그리고 기존의 form 태그를 아래 태그와 같이 수정 합니다.


<form:form name="form" id="form" role="form" modelAttribute="boardVO" method="post" action="${pageContext.request.contextPath}/board/saveBoard">

<form:hidden path="bid" />

<input type="hidden" name="mode" />


<div class="mb-3">

<label for="title">제목</label>

<form:input path="title" id="title" class="form-control" placeholder="제목을 입력해 주세요" />

</div>

<div class="mb-3">

<label for="reg_id">작성자</label>

<form:input path="reg_id" id="reg_id" class="form-control" placeholder="이름을 입력해 주세요"  />

</div>

<div class="mb-3">

<label for="content">내용</label>

<form:textarea path="content" id="content" class="form-control" rows="5" placeholder="내용을 입력해 주세요" />

</div>

<div class="mb-3">

<label for="tag">TAG</label>

<form:input path="tag" id="tag" class="form-control" placeholder="태그를 입력해 주세요" />

</div>

</form:form>


붉은 색 부분이 변경된 부분 입니다.

<form:form> 태그는 모두 form 이라는 키워드를 사용 합니다. 

그리고 name 이라는 속성 대신 path라는 속성을 사용합니다.


여기에 기존에 없던 두 가지 요소가 아래와 같이 추가 되어 있습니다.


<form:hidden path="bid" />

<input type="hidden" name="mode" />


이 요소들은 숨김처리 되어 화면에는 보이지 않으나, 데이터를 서버로 전송 할 때 반드시 필요한 데이터들 입니다.

그리고 숨김처리된 두 요소를 사용하는 방식에서 차이가 있습니다.

bid는  <form:form> 태그를 사용한 반면, mode 는 일반적인 HTML form 태그를 사용하였습니다.

이것은 Form태그 중간에 사용된 modelAttribute="boardVO" 와 관련이 있는데 

boardVO는 Controller에서 넘어온 boardVO 입니다.

boardVO 에는 mode 라는 프로퍼티를 가지고 있지 않기 때문에, 

<form:form> 태그를 사용하지 않고 일반적인 form 태그를 사용하여야 합니다.


마지막으로 입력폼에 추가할 내용은 수정할 데이터들을 입력폼에 셋팅하는 작업 입니다.

아래와 같은 구문을 스크립트에 추가 합니다.

$(document).ready(function(){

var mode = '<c:out value="${mode}"/>';

if ( mode == 'edit'){

//입력 폼 셋팅

$("#reg_id").prop('readonly', true);

$("input:hidden[name='bid']").val(<c:out value="${boardContent.bid}"/>);

$("input:hidden[name='mode']").val('<c:out value="${mode}"/>');

$("#reg_id").val('<c:out value="${boardContent.reg_id}"/>');

$("#title").val('<c:out value="${boardContent.title}"/>');

$("#content").val('<c:out value="${boardContent.content}"/>');

$("#tag").val('<c:out value="${boardContent.tag}"/>');

}

});


위 코드는 브라우저의 모든 요소들이 로딩된 이후 Controller 에서 넘어온 게시글에 대한 데이터를

각각의 요소에 셋팅하는 내용입니다.

작성자 이름은 수정하지 못하도록 readonly 속성을 설정하였습니다.


상세 내역 화면에서 [수정] 버튼을 클릭하여

데이터가 정상적으로 입력폼에 셋팅 되는지 확인합니다.




데이터 저장을 위한 Controller 수정

데이터를 수정하고, 변경된 데이터를 저장하기 위해 [저장] 버튼을 클릭하면

신규 데이터 입력과 같이 Controller의 saveBoard() 메소드에서 처리할 예정입니다.

하지만 지금의 saveBoard() 메소드는 신규 데이터만 입력 받도록 처리 되어 있으므로 

수정 데이터를 처리 할 수 있도록 아래와 같이 코드를 수정합니다.


@RequestMapping(value = "/saveBoard", method = RequestMethod.POST)

public String saveBoard(@ModelAttribute("boardVO") BoardVO boardVO

, @RequestParam("mode") String mode

, RedirectAttributes rttr) throws Exception {

if (mode.equals("edit")) {

boardService.updateBoard(boardVO);

} else {

boardService.insertBoard(boardVO);

}


return "redirect:/board/getBoardList";

}


추가 및 수정 된 부분은 붉은 표시가 된 부분입니다.

화면에서 숨김데이터로 넘어온 mode 값을 기준으로 신규 데이터 인지, 수정 데이터 인지 구분을 합니다.

여기서 mode 값이 'edit' 라면 데이터를 수정할 updateBoard() 메소드를 호출하게 되고,

아니면 신규 데이터 이므로 데이터를 입력할 insertBoard() 메소드를 호출 합니다.


상세내역을 수정 후 [저장] 버튼을 클릭해 봅니다.

다시 리스트 화면으로 이동하게 되는데, 데이터가 정상적으로 수정이 되었는지 확인해 봅니다.

(전 제목에 '- 수정' 이라는 문구를 추가하여 테스트 하였습니다. 따라서 목록에서 제목이 수정된 것을 확인 할 수 있었습니다.)




게시글 삭제를 위한 이벤트 추가

게시글 삭제는 수정 작업에 비해 매우 간단 합니다.

우선 아직 만들어 놓지 않은 [삭제] 버튼의 클릭 이벤트를 만듭니다.


boardContent.jsp 추가 내용

<script>

//목록으로 이동

$(document).on('click', '#btnList', function(){

location.href = "${pageContext.request.contextPath}/board/getBoardList";

});

//수정 버튼 클릭 이벤트

$(document).on('click', '#btnUpdate', function(){

var url = "${pageContext.request.contextPath}/board/editForm";

url = url + "?bid="+${boardContent.bid};

url = url + "&mode=edit";


location.href = url;

});

//삭제 버튼 클릭 이벤트

$(document).on('click', '#btnDelete', function(){

    var url = "${pageContext.request.contextPath}/board/deleteBoard";

    url = url + "?bid=" + ${boardContent.bid};

location.href = url;

});

</script>



Service 수정 (게시글 삭제)

BoardService.java 추가 내용

public void deleteBoard(int bid) throws Exception;


BoardServiceImpl.java 추가 내용

@Override

public void deleteBoard(int bid) throws Exception {

boardDAO.deleteBoard(bid);

}



Controller 수정 (게시글 삭제)

BoardController.java 추가 내용

@RequestMapping(value = "/deleteBoard", method = RequestMethod.GET)

public String deleteBoard(RedirectAttributes rttr, @RequestParam("bid") int bid) throws Exception {

boardService.deleteBoard(bid);

"redirect:/board/getBoardList";

}


이제 상세내역 화면에서 [삭제] 버튼을 클릭하여

데이터가 삭제 되는지 확인해 봅니다.






※ 포스팅에 오타나 잘못된 부분, 추가적으로 더 알고 싶은 부분이 있으면 댓글 주세요~


반응형

관련글 더보기