관리 메뉴

Just Do it

Part 3) 기본적인 웹 게시물 관리 (Ch 9 & 10) 본문

신입 개발자가 되기 위해 공부했던 독학 자료들/코드로 배우는 스프링 웹프로젝트

Part 3) 기본적인 웹 게시물 관리 (Ch 9 & 10)

Seojoo21 2022. 2. 16. 18:39

* 이 카테고리의 글은 <코드로 배우는 스프링 웹 프로젝트> 에서 각 파트별로 진행하는 프로젝트의 흐름을 보기 위해 각 장의 내용을 간단히 요약한 것이다.  

 

* 출처: 코드로 배우는 스프링 웹 프로젝트 개정판, 구멍가게 코딩단, 남가람북스 

 

 

Ch9. 비즈니스 계층 

- 비즈니스 계층은 고객의 요구사항을 반영하는 계층으로 프레젠테이션 계층과 영속 계층의 중간 다리 역할을 하게 된다.

- 영속 계층은 데이터베이스를 기준으로 해서 설계를 나눠 구현하지만, 비즈니스 계층은 로직을 기준으로 해서 처리하게 된다. 

- 예컨대, '쇼핑몰에서 상품을 구매한다'고 가정해보자. 해당 쇼핑몰의 로직이 '물건을 구매한 회원에게는 포인트를 올려준다'고 하면 영속 계층의 설계는 '상품'과 '회원'으로 나누어서 설계하게 된다. 

- 반면에 비즈니스 계층은 상품 영역과 회원 영역을 동시에 사용해서 하나의 '구매 서비스' 로직을 처리하게 된다.

- 현재 예제는 단일한 테이블을 사용하고 있기 때문에 위와 같은 구조는 아니지만, 설계를 할 때는 원칙적으로 영역을 구분해서 작성해야 한다. 

- 일반적으로 비즈니스 영역에 있는 객체들은 '서비스(Service)'라는 용어를 많이 사용한다. 

 

9.1) 비즈니스 계층의 설정 

- 프로젝트 내 org.zerock.service라는 패키지를 작성한다.

- 설계를 할 때 각 계층 간의 연결은 인터페이스를 이용해서 느슨한 연결을 한다. 그래서 게시물은 BoardService 인터페이스와 인터페이스를 구현한 BoardServiceImpl 클래스를 선언한다.

 

- BoardService 메서드를 설계할 때 메서드 이름은 현실적인 로직의 이름을 붙이는 것이 관례이다.

- 명백하게 반환해야 할 데이터가 있는 'select'를 해야 하는 메서드는 리턴 타입을 지정할 수 있다.

- 특정한 게시물을 가져오는 get() 메서드와 전체 리스트를 구하는 getList()의 경우 처음부터 메서드의 리턴 타입을 결정해서 진행할 수 있다. 

 

- BoardService 인터페이스를 구현하는 구현체는 BoardServiceImpl이라는 클래스로 작성한다.

- BoardServiceImpl 클래스에 가장 중요한 부분은 @Service 애너테이션이다. 

- @Service 애너테이션: 계층 구조상 주로 비즈니스 영역을 담당하는 객체임을 표시하기 위해 사용한다. 작성된 애너테이션은 패키지를 읽어 들이는 동안 처리한다.

- BoardServiceImpl이 정상적으로 동작하기 위해서는 BoardMapper 객체가 필요하다. 이는 @Autowired와 같이 직접 설정해줄 수 있고, Setter를 이용해서 처리할 수도 있다.

- spring 4.3부터는 단일 파라미터를 받는 생성자의 경우에는 필요한 파라미터를 자동으로 주입할 수 있다.

- @AllArgsConstructor는 모든 파라미터를 이용하는 생성자를 만들고 자동으로 주입해준다.

* 만일 생성자를 만들지 않을 경우에는 @Setter(onMethod_={@Autowired}) 를 이용해서 처리한다. 

 

9.1.1) 스프링의 서비스 객체 설정(root-context.xml)

비즈니스 계층의 인터페이스와 구현 클래스가 작성되었다면, 이를 스프링의 빈으로 인식하기 위해서 root-context.xml에 @Service 어노테이션이 있는 org.zerock.service 패키지를 스캔하도록 추가해야한다. (아래 코드를 root-context.xml에 추가해줘야 함) 

<context:component-scan base-package="org.zerock.service">
	</context:component-scan>

 

9.2) 비즈니스 계층의 구현과 테스트 

BoardMapper와 BoardService, BoardServiceImpl에 대한 구조 설정이 완료되었으므로 'src/test/java'밑에 org.zerock.service.BoardServiceTests 클래스를 작성해 테스트 작업을 진행한다. 

 

9.2.1) 등록 작업의 구현과 테스트

- 등록 작업은 BoardServiceImpl에서 파라미터로 전달되는 BoardVO 타입의 객체를 BoardMapper를 통해서 처리한다.

 

9.2.2) 목록(리스트) 작업의 구현과 테스트 

- BoardServiceImpl 클래스에서 현재 테이블에 저장된 모든 데이터를 가져오는 테스트.

- BoardMapper 인터페이스의 getList() 메서드를 이용한다.

 

9.2.3) 조회 작업의 구현과 테스트

 - 조회는 게시물의 번호가 파라미터이고 BoardVO의 인스턴스가 리턴된다. 

 

9.2.4) 삭제/수정 구현과 테스트

- 삭제/수정은 메서드의 리턴타입을 void로 설계할 수도 있지만 엄격하게 처리하기 위해서 Boolean 타입으로 처리한다. 

 

Ch10. 프레젠테이션(웹)계층의 CRUD 구현

- 비즈니스 계층의 구현까지 모든 테스트가 진행되었다면 이제 남은 작업은 프레젠테이션 계층인 웹의 구현이다.

 

10.1) Controller의 작성 

- 스프링 MVC의 Controller는 하나의 클래스 내에서 여러 메서드를 작성하고, @RequestMapping 등을 이용해서 URL을 분기하는 구조로 작성할 수 있기 때문에 하나의 클래스에서 필요한 만큼 메서드의 분기를 이용하는 구조로 작성한다.

 

10.1.1) BoardController의 분석

- 작성하기 전에는 반드시 현재 원하는 기능을 호출하는 방식에 대해 다음과 같이 테이블로 정리한 후 코드를 작성하는 것이 좋다. 

- 테이블에서 From 항목은 해당 URL을 호출하기 위해서 별도의 입력화면이 필요하다는 것을 의미한다. 이에 대한 설계는 화면을 구성하는 단계에서 진행할 수 있다. 

Task URL Method Parameter From URL이동
전체 목록 /board/list GET      
등록 처리 /board/register POST 모든 항목 입력화면 필요 이동
조회 /board/read GET bno=123    
삭제 처리 /board/modify POST bno 입력화면 필요 이동
수정 처리 /board/remove POST 모든 항목 입력화면 필요 이동

 

10.2) BoardController의 작성

- BoardController는 org.zerock.controller 패키지에 선언하고 URL 분석된 내용들을 반영하는 메서드를 설계한다. 

 

10.2.1) 목록에 대한 처리와 테스트

- BoardController에서 전체 목록을 가져오는 처리를 먼저 작성한다. 

- BoardController는 BoardService타입의 객체와 연동해야하므로 의존성에 대한 처리도 같이 진행한다.

- 테스트 코드는 기존과 좀 다르게 진행된다. 매번 Tomcat을 실행하는 것이 불편하기 때문이다. 

- WAS를 실행하지 않기 위해서는 약간의 추가적인 코드가 필요하지만 서버를 반복적으로 실행하는 단계를 줄여줄 수 있어 Controller를 테스트 할 때 한번 쯤 고려해 볼 만한 방식이다.  

 

10.2.2) 등록 처리와 테스트

- 등록 작업이 끝난 후 다시 목록 화면으로 이동할 수 있도록 메서드의 파라미터에 RedirectAttributes를 파라미터로 지정한다. 

- 리턴문은 return "redirect:/board/list"; 로 작성한다. 

 

10.2.3) 조회 처리와 테스트

- 등록 처리와 유사하게 처리한다.

- 특별한 경우가 아니라면 조회는 GET 방식으로 처리하므로, @GetMapping을 이용한다. 

 

10.2.4) 수정 처리와 테스트

- 수정 작업 또한 등록 처리와 유사하다.

- 변경된 내용을 수집해서 BoardVO 파라미터로 처리하고, BoardService를 호출한다. 

- 수정 작업을 시작하는 화면의 경우에는 GET방식으로 접근하지만, 실제 작업은 POST방식으로 동작하므로 @PostMapping을 이용해서 처리한다.  

- 수정 작업이 끝난 후 다시 목록 화면으로 이동할 수 있도록 메서드의 파라미터에 RedirectAttributes를 파라미터로 지정한다.

- 리턴문은 return "redirect:/board/list"; 로 작성한다. 

 

10.2.5) 삭제 처리와 테스트

- 삭제 처리도 조회와 유사하게 처리한다. 

- 삭제는 반드시 POST 방식으로만 처리한다. 

- 삭제 작업이 끝난 후 다시 목록 화면으로 이동할 수 있도록 메서드의 파라미터에 RedirectAttributes를 파라미터로 지정한다.

- 리턴문은 return "redirect:/board/list"; 로 작성한다.