Spring Mybatis (4) 게시글 쓰기, 수정 기능

강서진·2024년 1월 25일
0

Spring

목록 보기
15/18
post-custom-banner

2번째 필수강의 ch4. 6강 요약

/write로 가는 버튼을 게시글 목록 화면에 새로 만들고, 버튼을 누르면 /write로 GET 요청을 보내게 만든다. 게시글 조회에 사용했던 board.jsp를 그대로 사용하되, 글을 쓸 때는 옵션으로 readonly를 주지 않는다. 두 가지를 구분하기 위해 mode를 생성하고, mode값이 new면 readonly를 해제하도록 코드를 작성한다.

// BoardController
---
  @GetMapping("/write")
  public String write(Model m){
    m.addAttribute("mode", "new");
    return "board";
  }
// Board.jsp
---
...
  <h2>게시물 ${mode=="new"?"쓰기":"읽기"}</h2>
  <form action="" id="form">
    <input type="hidden" name="bno" value="${boardDto.bno}" ${mode=="new"?'':'readonly="readonly"'}>
    <input type="text" name="title" value="${boardDto.title}" ${mode=="new"?'':'readonly="readonly"'}>
    <textarea name="content" id="" cols="30" rows="10" ${mode=="new"?'':'readonly="readonly"'}>${boardDto.content}</textarea>
...

읽기와 쓰기 페이지를 따로 만들면 코드를 쓸 때는 편하지만, 유지보수 면에서는 수정사항이 있으면 두 곳을 고쳐야 하기 때문에 같은 화면을 쓴다.

게시글 내용을 입력하고 등록 버튼을 누르면, /write로 POST 요청을 보내도록 한다.

    $('#writeBtn').on("click", function(){
      let form = $('#form');
      form.attr("action","<c:url value='/board/write'/>");
      form.attr("method","post");
      form.submit();
    });

요청으로 넘어온 게시글을 DB에 저장한 후에는 다시 게시글 목록 첫 페이지로 redirect하도록 작성한다. 예외처리도 추가하여, 실행 결과가 1이 아니면 예외를 던지도록 처리하였다. 예외가 발생하면 다시 작성 화면으로 돌아가는데, 작성한 내용이 사라지지 않도록 model에 저장해준다.

@PostMapping("/write")
  public String writePost(BoardDto boardDto, HttpSession session, Model m, RedirectAttributes rattr){
    String writer = (String) session.getAttribute("id");
    boardDto.setWriter(writer);

    try{
      int count = boardService.write(boardDto);
      rattr.addFlashAttribute("msg", "write_ok");
      if (count!=1) throw new Exception("글 작성 실패");

      return "redirect:/board/list";
    } catch (Exception e){
      e.printStackTrace();
      m.addAttribute("boardDto", boardDto);
      rattr.addFlashAttribute("msg", "write_err");
      return "board";
    }
  }

게시글 삭제처럼 게시글 등록도 등록에 성공하면 게시글 목록 화면에서 alert를 띄우도록 한다. 마찬가지로 새로고침했을 때 반복적으로 나오지 않도록 RedirectAttribute의 addFlashAttribute를 활용한다.
게시글 작성에 실패했을 경우 작성 화면에 그대로 머물러있기 때문에 board.jsp에 스크립트를 추가해준다.

<script>
  let msg = "${msg}"
  if(msg=="del_ok") alert("성공적으로 삭제되었습니다.");
  if(msg=="del_err") alert("삭제에 실패했습니다.");
  if(msg=="write_ok") alert("성공적으로 작성하였습니다.");
</script>

테스트해보면 잘 작동하는 것을 확인할 수 있다. 예외가 발생했을 때도 제대로 돌아가는지 보려면 DAO에서 예외를 던지도록 잠시 주석처리한 후 테스트해보면 된다.


다음으로 게시글 수정 기능을 구현해본다. 게시글 조회 화면에서 수정 버튼을 클릭하면 readonly 상태가 해제되게 만든다. jQuery를 활용하여 수정 버튼이 등록 버튼으로 바꾸고, 등록 버튼을 누르면 글 작성 화면과 똑같이 동작하도록 한다.

    $('#modifyBtn').on("click", function(){
      let form = $('form');
      let isReadOnly=$("input[name=title]").attr('readonly');

      if(isReadOnly=='readonly'){
          $("input[name=title]").attr('readonly',false);
          $("textarea").attr('readonly',false);
          $("#modifyBtn").html("등록");
          $("h2").html("게시물 수정");
          return;
        }

        form.attr("action","<c:url value='/board/modify'/>");
        form.attr("method","post");
        form.submit();
        });

다만 이 때는 /modify로 POST 요청이 날아가고, insert가 아니라 update가 일어난다.

  @PostMapping("/modify")
  public String modify(BoardDto boardDto, HttpSession session, Model m, RedirectAttributes rattr) {
    String writer = (String) session.getAttribute("id");
    boardDto.setWriter(writer);

    try {
      int count = boardService.modify(boardDto);
      rattr.addFlashAttribute("msg", "modify_ok");
      if (count != 1) throw new Exception("글 수정 실패");

      return "redirect:/board/list";
    } catch (Exception e) {
      e.printStackTrace();
      m.addAttribute("boardDto", boardDto);
      rattr.addFlashAttribute("msg", "modify_err");
      return "board";
    }
  }

추가로, 게시글을 수정하고 난 후에는 게시글 목록 첫 페이지가 아닌 해당하는 게시글 페이지로 돌아갈 수 있도록 수정해볼 필요가 있다.

post-custom-banner

0개의 댓글