26/07/20 IL(I Learned) - Step 1

Spring MVC와 Controller의 역할 이해

기존 JDBC 프로젝트를 Spring Framework 기반으로 발전시키면서 Spring MVC(Model-View-Controller) 구조를 직접 구현해 보았다. 이전에는 main() 메서드에서 직접 Repository를 호출하여 CRUD를 수행했지만, 이번 프로젝트에서는 Controller → Service → Repository 구조를 적용하여 각 계층의 역할을 분리하였다.

또한 JSP를 View로 사용하면서 사용자의 요청(Request)이 어떻게 Controller로 전달되고, Controller가 Service와 Repository를 거쳐 데이터를 조회한 후 다시 View로 전달하는지 전체적인 흐름을 이해할 수 있었다.

Spring Boot를 사용할 때는 이러한 과정이 자동으로 이루어진다고만 생각했는데, 이번 실습을 통해 MVC 패턴이 왜 필요한지, 그리고 각 계층이 어떤 역할을 수행하는지를 보다 깊게 이해할 수 있었다.


1) MainController

학습 내용상세 내용
@Controller해당 클래스를 Spring MVC의 Controller로 등록한다. 사용자의 요청을 가장 먼저 처리하는 역할을 수행한다.
@RequestMappingController가 처리할 기본 URL을 지정한다.
@GetMappingGET 요청을 처리하는 메서드를 지정한다. 주로 조회 기능에서 사용된다.
@PostMappingPOST 요청을 처리하는 메서드를 지정한다. 데이터 생성이나 수정 시 사용된다.
ModelController에서 View(JSP)로 데이터를 전달하는 객체이다.
Redirect작업 완료 후 새로운 요청을 발생시키기 위해 사용하는 방식이다.
@Controller
@RequestMapping("/")
@RequiredArgsConstructor
public class MainController {

    private final BankService bankService;

    @GetMapping("/")
    public String index(Model model){

        model.addAttribute(
                "accounts",
                bankService.getAccounts()
        );

        return "index";

    }

}

이번 실습에서는 사용자가 브라우저에서

http://localhost:8080/

를 요청하면

가장 먼저 DispatcherServlet이 요청을 받는다.

DispatcherServlet은

"/"

URL을 처리할 Controller를 찾는다.

그 결과

@GetMapping("/")

이 실행된다.


Controller에서는

bankService.getAccounts();

를 호출하여

Service에게

"전체 계좌 목록을 가져와."

라고 요청한다.

Controller는

SQL을 작성하지 않는다.

DB와 직접 연결하지도 않는다.

오직

사용자의 요청을 받고

Service를 호출한 뒤

결과를 View로 전달하는 역할만 수행한다.


조회된 데이터는

model.addAttribute()

를 이용하여

JSP에게 전달된다.

model.addAttribute(
        "accounts",
        bankService.getAccounts()
);

Model 객체는

일종의

Map<String,Object>

처럼 동작한다.

즉,

accounts

라는 이름으로

JSP에게 데이터를 전달하는 것이다.

JSP에서는

${accounts}

를 이용하여 사용할 수 있다.


마지막으로

return "index";

를 반환하면

ViewResolver가

/WEB-INF/views/index.jsp

를 찾아 사용자에게 화면을 보여준다.


Spring MVC 요청 흐름

브라우저

↓

DispatcherServlet

↓

MainController

↓

BankService

↓

Repository

↓

Database

↓

Repository

↓

Service

↓

Controller

↓

Model

↓

index.jsp

↓

브라우저

이번 실습을 통해

Spring MVC는

각 객체가 자신의 역할만 수행하도록 설계되어 있다는 점을 이해하였다.


POST 요청

@PostMapping("/")

에서는

새로운 계좌를 생성한다.

bankService.makeAccount(dto);

가 호출되면

Service가 Repository에게

INSERT를 요청한다.

그리고

return "redirect:/";

를 수행한다.


Redirect를 사용하는 이유

처음에는

return "index";

를 하지 않고

redirect:/

를 사용하는지 이해되지 않았다.

하지만

POST 요청 후

바로 JSP를 반환하면

새로고침(F5)을 했을 때

POST 요청이 다시 실행된다.

즉,

계좌가

두 번 생성될 수 있다.

이를

중복 제출(Double Submit)

문제라고 한다.

그래서

POST가 끝나면

다시

GET 요청을 보내도록

Redirect를 사용하는 것이다.

이를

PRG(Post Redirect Get) 패턴

이라고 한다.


기능실무 사용
Controller모든 요청의 시작점
ModelView 데이터 전달
Redirect등록, 수정, 삭제 후 반드시 사용
ViewResolverThymeleaf, JSP 등을 찾아준다.
DispatcherServlet모든 요청을 관리하는 Front Controller

2) AccountController

학습 내용상세 내용
@PathVariableURL에 포함된 값을 변수로 받아오는 기능이다.
@ModelAttributeHTML Form의 데이터를 객체(DTO)로 자동 변환해준다.
계좌 수정수정할 계좌를 조회하고 변경 내용을 저장하였다.
계좌 삭제URL을 통해 전달된 id를 이용하여 데이터를 삭제하였다.
@GetMapping("/{accountId}")
public String showAccount(
        @PathVariable long accountId,
        Model model
){

    AccountViewDTO accountDto =
            bankService.findAccount(accountId);

    model.addAttribute(
            "account",
            accountDto
    );

    return "account";

}

이번 Controller에서는

URL에 포함된 값을

직접 변수로 받아왔다.

예를 들어

/account/3

이라는 요청이 들어오면

Spring은

@PathVariable long accountId

자동으로

3

을 넣어준다.

즉,

개발자가

직접

request.getParameter()

를 사용할 필요가 없다.

Spring이 자동으로 처리해준다.


수정 기능에서는

@ModelAttribute

를 사용하였다.

@PostMapping("/{id}")

사용자가 입력한

name=홍길동

Spring

AccountFormDTO

자동 생성

Service 호출

이 과정이 자동으로 이루어진다.


삭제 기능 역시

@GetMapping("/{id}/delete")

를 이용하여

Repository에게

삭제를 요청한다.

Controller는

삭제 SQL을 작성하지 않는다.

Service에게

삭제를 요청할 뿐이다.


Account 수정 흐름

사용자

↓

account.jsp

↓

POST /account/3

↓

AccountController

↓

BankService

↓

Repository

↓

UPDATE SQL

↓

DB

↓

Redirect

↓

GET /account/3

Spring MVC가 편리한 이유

예전 JDBC에서는

Scanner scanner

로 데이터를 입력받았다.

하지만

Spring에서는

HTML Form만 작성하면

자동으로

DTO 객체가 생성된다.

즉,

사용자 입력을

직접 파싱할 필요가 없다.


기능사용 이유
PathVariable상세조회
ModelAttributeForm 처리
DTO사용자 입력 검증
Redirect중복 제출 방지

느낀 점

느낀 점내용
Spring 자동 바인딩@ModelAttribute를 통해 Form 데이터가 DTO로 자동 변환되는 과정이 매우 편리하다고 느꼈다.
URL 설계@PathVariable을 사용하여 URL만으로 필요한 데이터를 전달받는 REST 방식의 장점을 이해하였다.
MVC 역할 분리Controller는 요청을 연결하는 역할만 수행하고 실제 비즈니스 로직은 Service가 담당한다는 점이 더욱 명확해졌다.
profile
예 마 함 가보입시더

0개의 댓글