[Spring framework] 프레젠테이션(웹) 계층의 CRUD 구현 (Controller)
Controller의 작성
스프링 MVC의 Controller은 하나의 클래스 내에서 여러 메서드를 작성하고, @RequestMapping 등을 이용해서 URL을 분기하는 구조로 작성할 수 있기 때문에 하나의 클래스에서 필요한 만큼 메서드의 분기를 이용하는 구조로 작성합니다.
과거에는 Controller 테스트를 하기 위해 WAS를 실행하고, 웹 화면을 만들어서 URL을 요청하여 테스트했습니다. 이 방법은 시간이 오래 걸리기 때문에 WAS를 실행하지 않고 테스트하는 방법을 익혀야 합니다.
BoardController의 분석
작성하기 전에 원하는 기능을 호출하는 방식에 대해 테이블로 정리 후 코드로 작성합니다.
TASK | URL | METHOD | PARAMETER | FROM | URL 이동 |
전체 목록 | /board/list | GET | |||
등록 처리 | /board/register | POST | 모든 항목 | 입력화면 필요 | 이동 |
조회 | /board/read | GET | bno=123 | ||
삭제 처리 | /board/remove | POST | bno | 입력화면 필요 | 이동 |
수정 처리 | /board/modify | POST | 모든 항목 | 입력화면 필요 | 이동 |
BoardController의 작성
BoardController는 com.project.controller 패키지에 선언하고 URL 분석된 내용들을 반영하는 메서드를 설계합니다.
@Controller 어노테이션을 추가해서 스프링의 빈으로 인식할 수 있게 하고, @RequestMapping을 통해서 '/board'로 시작하는 모든 처리를 BoardController가 하도록 지정합니다. BoardController가 속한 com.project.controller 패키지는 servlet-context.xml에 기본으로 설정되어 있으므로 별도의 설정이 필요하지 않습니다. (Java 설정의 경우 ServletConfig 클래스에서 @ComponentScan 으로 해당 패키지를 설정합니다.)
1. BoardController는 BoardService타입의 객체와 같이 연동해야 하므로 의존성에 대한 처리도 같이 진행합니다.
2. BoardController는 BoardService에 대해서 의존적이므로 @AllArgsConstructor를 이용해서 생성자를 만들고 자동으로 주입하도록 합니다. (생성자를 만들지 않을 경우에는 @Setter(onMethod_ = { @Autowired })를 이용해 처리합니다.)
3. list( ) 는 나중에 게시물의 목록을 전달해야 하므로 Model을 파라미터로 지정하고, 이를 통해서 BoardServiceImpl 객체의 getList() 결과를 담아 전달합니다. (addAttribute)
* BoardController 테스트는 스프링의 테스트 기능을 통해 확인할 수 있습니다.
* src/test/java 에 com.project.controller 패키지에 BoardControllerTests 클래스를 선언합니다.
* controller 테스트 코드는 기존과 좀 다르게 진행되는데 그 이유는 URL을 테스트하기 위해 WAS를 실행하는 단계를 생략하기 위함입니다.
BoardControllerTests 클래스 작성하기
자동 입력되는 import 영역 생략
어노테이션
@RunWith - JUnit으로 실행하기 위한 설정
@WebAppConfiguration - Servlet의 ServletContext를 이용하기 위해서인데, 스프링에서 WebApplicationContext라는 존재를 이용하기 위해서입니다.
어노테이션
@Before가 적용된 setup( )에서는 import 할 때 JUnit을 이용해야 합니다. @Before가 적용된 메서드는 모든 테스트 전에 매번 실행되는 메서드가 됩니다.
MockMvc는 '가짜 mvc' 라고 생각하면 되고, 가짜로 URL과 파라미터 등을 브라우저에서 사용하는 것처럼 만들어서 Controller를 실행해볼 수 있습니다. testList( )는 MockMvcRequestBuilders라는 존재를 이용해서 GET 방식의 호출을 합니다. 이후에는 BoardController의 getList( )에서 반환된 결과를 이용해서 Model에 어떤 데이터들이 담겨 있는지 확인합니다. Tomcat을 통해서 실행되는 방식이 아니므로 기존의 테스트 코드를 실행하는 것과 동일하게 실행합니다.
testList( )를 실행한 결과는 데이터베이스에 저장된 게시물들을 볼 수 있습니다.
테스트 실행결과
위와 같은 방식으로 다음 등록, 조회, 수정, 삭제에 대해 보겠습니다.
등록 처리와 테스트
조회 처리와 테스트
수정 처리와 테스트
삭제 처리와 테스트
등록 처리와 테스트
BoardController에 POST 방식으로 처리되는 register( )를 작성합니다.
register( )는 String return 타입으로 지정하고, RedirectAttributes 를 파라미터로 지정합니다. 이는 등록 작업이 끝난 후 다시 목록 화면으로 이동하기 위함인데, 추가적으로 새롭게 등록된 게시물의 번호를 같이 전달하기 위해서 RedirectAttributes를 이용합니다. 리턴 시에는 'redirect:' 접두어를 사용하는데 이를 이용하면 스프링 MVC가 내부적으로 response.sendRedirect( )를 처리해 주기 때문에 편리합니다.
테스트 코드는 아래와 같이 작성합니다.
테스트할 때 MockMvcRequestBuilders의 post( )를 이용하면 POST 방식으로 데이터를 전달할 수 있고, param( )을 이용해서 전달해야 하는 파라미터들을 지정할 수 있습니다. <input> 태그와 유사한 역할로 볼 수 있습니다.
실행결과
BoardVO 객체로 올바르게 데이터가 바인딩된 결과를 볼 수 있고, 중간에 SQL의 실행 결과가 보입니다. 마지막에는 최종 반환 문자열을 확인할 수 있습니다.
조회 처리와 테스트
특별한 경우가 아니면 조회는 GET 방식으로 처리합니다. @GetMapping을 이용합니다.
Controller에 get( ) 메서드 추가
BoardController의 get( ) 메서드에는 bno 값을 좀 더 명시적으로 처리하는 @RequestParam을 이용해서 지정합니다.
(파라미터 이름과 변수 이름을 기준으로 동작하기 때문에 생략해도 무방합니다. ) 또한 화면 쪽으로 해당 번호의 게시물을 전달해야 하므로 Model을 파라미터로 지정합니다.
Test 코드 작성
특정 게시물을 조회할 때 반드시 'seq_bno'라는 파라미터가 필요하므로 param( )을 통해서 추가하고 실행합니다.
실행결과
파라미터가 제대로 수집되었는지 확인, SQL의 처리결과 확인, 마지막에는 Model에 담겨 있는 BoardVO 인스턴스의 내용을 확인할 수 있습니다.
수정 처리와 테스트
수정은 등록과 유사하여 BoardVO를 파라미터로 사용해 BoardService를 호출합니다.
BoardController 클래스에 modify 메서드 추가
service.modify( )는 수정 여부를 boolean으로 처리하므로 이를 이용해서 성공한 경우에만 RedirectAttributes에 추가합니다.
TEST 코드 작성
com.project.controller.BoardControllerTests 클래스
테스트 실행 로그
Modify 후 데이터 확인해보기
삭제 처리와 테스트
삭제 처리도 조회와 유사하게 BoardController와 테스트 코드를 작성합니다.
삭제는 반드시 POST 방식으로만 처리합니다.
BoardController 클래스에 메서드 추가
테스트 코드는 기존의 등록 처리와 유사합니다.
테스트 코드 작성
com.project.controller.BoardControllerTests 클래스 일부
실행결과
테이블에 존재하는 seq_bno를 확인하여 삭제 테스트 실행 후 정상적으로 삭제가 되었다면 테이블에서 해당 seq_bno를 갖는 row가 삭제된 것을 확인할 수 있습니다.
이번 글에서는 프레젠테이션(웹) 계층에서 CRUD 처리와 테스트를 해보았습니다.
도움이 되셨다면 광고 한 번 클릭 부탁드립니다.
한 번의 클릭이 글을 쓰는 큰 동기부여가 됩니다! :)
'java, spring' 카테고리의 다른 글
[Spring] 스프링 jsp 페이지, ViewResolver, ResourceHandler (0) | 2021.07.06 |
---|---|
[Spring] MariaDB와 log4jdbc 연결 오류 해결방법 (1) | 2021.06.30 |
[Spring framework] 비즈니스 계층 CRUD (0) | 2021.06.24 |
[Spring] 영속 영역의 CRUD 구현 (MyBatis - CRUD) (0) | 2021.06.21 |
[Spring] 영속 계층의 CRUD 구현을 위한 환경설정 (0) | 2021.06.19 |