[스프링 부트] 17. 입력 구현

lhs's avatar
Nov 18, 2024
[스프링 부트] 17. 입력 구현
 

1. save-form.mustache

{{> layout/header}} <section> <form action="/board/save" method="post" enctype="application/x-www-form-urlencoded"> <input type="text" name="title" placeholder="제목"><br> <input type="text" name="content" placeholder="내용"><br> <button type="submit">글쓰기</button> </form> </section> </body> </html>
  • 모든 input 태그를 form 태그로 감싸서 데이터를 한번에 전송할 수 있도록 한다.
  • action 속성에 데이터를 전송할 URL 주소를 설정한다.
    • 스프링을 연습하기 위해 JavaScript 없이 HTML 1.0 버전으로 상정하여 연습하며, GET과 POST만 사용할 수 있으므로 주소에 save를 추가한다.
  • methodpost로 설정하여 데이터를 서버에 전송할 방식을 지정한다.
  • enctypeapplication/x-www-form-urlencoded로 설정하여 데이터가 URL-encoded 형식으로 전송되도록 한다.
  • input 태그의 name 속성은 전송되는 데이터의 키값이 되고, 사용자가 입력한 값이 해당 키값의 밸류가 된다.
  • 제출을 위한 submit 버튼을 생성하여 데이터를 전송할 수 있도록 한다.

2. BoardRepository

@RequiredArgsConstructor @Repository public class BoardRepository { private final EntityManager entityManager; public void save(String title, String content) { Query q = entityManager.createNativeQuery("insert into board_tb(title,content,created_at) values(?,?,now())"); q.setParameter(1, title); q.setParameter(2, content); q.executeUpdate(); } }
  • BoardRepositorysave 메서드를 구현하여 게시글의 titlecontent를 DB에 저장한다.
  • save 메서드는 titlecontent를 매개변수로 받아 insert 쿼리를 생성하고, executeUpdate 메서드를 호출해 DB에 쿼리를 실행한다.

3. BoardRepostioryTest

@Import(BoardRepository.class) @DataJpaTest public class BoardRepositoryTest { @Autowired BoardRepository boardRepository; @Test public void save_test() { // given String title = "제목6"; String content = "내용6"; // when boardRepository.save(title, content); // then(eye) Board board = boardRepository.findById(6); System.out.println(board.getId()); System.out.println(board.getTitle()); System.out.println(board.getContent()); System.out.println(board.getCreatedAt()); } }
  • BoardRepository에서 구현한 save 메서드를 테스트한다.
  • @DataJpaTest 어노테이션은 테스트 후 트랜잭션을 롤백해 DB 상태를 원래대로 복원하여 독립적인 테스트 환경을 제공한다.
  • 테스트의 3가지 단계
    • given : 테스트를 위한 입력 값을 설정하는 단계
      • DB에 저장할 titlecontent 값을 설정한다.
    • when : 테스트할 메서드를 실행하는 단계
      • boardRepository.save() 메서드를 호출하여 DB에 데이터를 저장한다.
    • then : 결과를 검증하는 단계
      • 출력으로 결과를 검증하는 방식으로 대체하였다.

4. BoardRequest

public class BoardRequest { @Data public static class SaveDTO { private String title; private String content; } }
  • 폼에서 입력받은 데이터를 저장하기 위한 객체 SaveDTO를 정의한다.

5. BoardController

@RequiredArgsConstructor @Controller public class BoardController { private final BoardService boardService; @PostMapping("/board/save") public String save(BoardRequest.SaveDTO saveDTO) { boardService.게시글쓰기(saveDTO); return "redirect:/"; // response.sendRedirect("/"); // response.setStatus(302); // response.setHeader("Location", "/"); } @GetMapping("/save-form") public String saveForm() { return "save-form"; } }
  • save:
    • @PostMapping을 통해 /board/save 경로로 들어오는 POST 요청을 save 메서드에서 처리한다.
    • save 메서드에서는 BoardRequest.SaveDTO 객체로 폼 데이터를 입력받는다.
    • boardService에서 게시글쓰기 메서드를 호출하여 saveDTO의 정보를 DB에 저장한다.
    • "redirect:/" 값을 반환하여 / 경로로 리다이렉트한다.
    • 리다이렉트 방식:
      • Spring MVC: return "redirect:/";를 사용하여 리다이렉트를 처리한다.
      • 서블릿: response.sendRedirect("/"); 메서드를 사용하여 리다이렉트를 처리한다.
      • 직접 설정: response.setStatus(302); response.setHeader("Location", "/");를 사용하여 리다이렉트를 처리한다.
  • saveForm:
    • @GetMapping을 통해 /save-form 경로로 들어오는 GET 요청을 saveForm 메서드에서 처리한다.
    • saveForm 메서드는 "save-form" 뷰를 반환하여 폼을 표시한다.

6. BoardService

@RequiredArgsConstructor @Service public class BoardService { private final BoardRepository boardRepository; @Transactional public void 게시글쓰기(BoardRequest.SaveDTO saveDTO) { boardRepository.save(saveDTO.getTitle(), saveDTO.getContent()); } }
  • 게시글쓰기 메서드를 구현하여, saveDTO 데이터를 boardRepositorysave 메서드를 사용하여 DB에 저장한다.
  • @Transactional : 메서드 실행이 완료되면 커밋하고, 예외 발생 시 롤백하여 트랜잭션을 관리하는 어노테이션

7. 구현 테스트

notion image
  • 폼에 제목과 내용을 입력하고 글쓰기 버튼을 클릭하여 폼 데이터를 전송한다.
notion image
  • 게시판 목록으로 리다이렉트되는지 확인한다.
  • 게시글이 정상적으로 작성되었는지 확인한다.
Share article

LHS's Study Space