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