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를 추가한다.
method를post로 설정하여 데이터를 서버에 전송할 방식을 지정한다.
enctype을application/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();
}
}
BoardRepository에save메서드를 구현하여 게시글의title과content를 DB에 저장한다.
save메서드는title과content를 매개변수로 받아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에 저장할
title과content값을 설정한다. 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데이터를boardRepository의save메서드를 사용하여 DB에 저장한다.
@Transactional: 메서드 실행이 완료되면 커밋하고, 예외 발생 시 롤백하여 트랜잭션을 관리하는 어노테이션
7. 구현 테스트

- 폼에 제목과 내용을 입력하고 글쓰기 버튼을 클릭하여 폼 데이터를 전송한다.

- 게시판 목록으로 리다이렉트되는지 확인한다.
- 게시글이 정상적으로 작성되었는지 확인한다.
Share article