관리 메뉴

Rootable의 개발일기

Spring MVC 패턴 본문

Spring

Spring MVC 패턴

dev-rootable 2023. 4. 27. 10:38

📌 Spring MVC 패턴

 

Model, View, Controller 의 약자로, 요청에 대한 로직 수행과 뷰 렌더링 작업을 분리하기 위해 도입되었다.

 

동작 방식은 요청이 들어오면 Controller에서 인식하여 렌더링할 뷰를 선택한다. 여기서 View에 전달할 데이터가 있다면 Model이라는 객채에 담아 전달한다. 그리고 Controller가 가리키는 View는 Model의 값과 함께 화면을 렌더링하는 식으로 동작한다.

 

  • Model
    • 데이터를 가진 객체를 지칭한다. 데이터는 내부의 상태에 대한 정보를 가질 수도 있고, 모델을 표현하는 이름 속성으로 가질 수 있다. 모델의 상태에 변화가 있을 때 컨트롤러와 뷰에 이를 통보한다. 이와 같은 통보를 통해 뷰는 최신의 결과를 보여줄 수 있고, 컨트롤러는 모델의 변화에 따른 적용 가능한 명령을 추가, 제거, 수정할 수 있다.
  • View
    • 클라이언트 측 기술들(HTML, CSS, JS)을 모아둔 컨테이너다. 사용자가 볼 결과물을 생성하기 위해 Model로부터 정보를 얻어온다.
  • Controller
    • 사용자가 접근한 URL에 따라 사용자의 요청 사항을 파악한 후에 그 요청에 맞는 데이터를 Model에 요청하고, 데이터를 View에 반영해서
      사용자에게 알려준다.
    • Model에 명령을 보냄으로써 View의 상태를 변경할 수 있다.
    • 컨트롤러가 관련된 Model에 명령을 보냄으로써 View의 표시 방법을 바꿀 수 있다.

 

Reference:

https://cocoon1787.tistory.com/733

 

[개발상식] MVC 패턴이란? (Model-View-Controller)

🚀 이번 포스팅은 개발자 면접에서 자주 나오는 질문 중의 하나인 "MVC패턴"에 대한 내용입니다. MVC패턴의 의미와 사용해야 하는 이유, 사용 예시 등등에 대해 알아보겠습니다. 💡 MVC 패턴이란?

cocoon1787.tistory.com

 

🔎 MVC 예제

 

✔ Model

 

@Data
public class ItemUpdateForm {

    @NotNull
    private Long id;

    @NotBlank
    private String itemName;

    @NotNull
    @Range(min = 1000, max = 1000000)
    private Integer price;

    private Integer quantity;

}

 

위 객체는 수정용 폼 객체다. 즉, 수정 상황에서 사용자의 입력 값을 저장하는 객체로 데이터를 가진 객체인 Model이라 볼 수 있다. 아래 사진처럼 사용자가 입력한 내용을 그대로 담고 있다.

 

입력한 수정 데이터

 

✔ View

 

    <div>
        <label for="itemId" th:text="#{label.item.id}">상품 ID</label>
        <input type="text" id="itemId" name="itemId" class="form-control" value="1" th:value="${item.id}" readonly>
    </div>
    <div>
        <label for="itemName" th:text="#{label.item.itemName}">상품명</label>
        <input type="text" id="itemName" name="itemName" class="form-control" value="상품A" th:value="${item.itemName}" readonly>
    </div>
    <div>
        <label for="price" th:text="#{label.item.price}">가격</label>
        <input type="text" id="price" name="price" class="form-control" value="10000" th:value="${item.price}" readonly>
    </div>
    <div>
        <label for="quantity" th:text="#{label.item.quantity}">수량</label>
        <input type="text" id="quantity" name="quantity" class="form-control" value="10" th:value="${item.quantity}" readonly>
    </div>

 

위와 같은 HTML 코드로 사용자가 볼 화면을 정의한다. 또한, 타임리프와 같은 서버 사이드 렌더링 도구를 통해 현재 Model에 들어 있는 값을 그대로 가져와서
화면에 보여준다.

 

수정 결과 화면

 

위 화면은 수정 후 화면이다. Controller의 도움으로 Model로부터 정보를 얻어 와 그대로 출력하는 것이다.

 

✔ Controller

 

    @PostMapping("/{itemId}/edit")
    public String edit(@PathVariable Long itemId, @Validated @ModelAttribute("item") ItemUpdateForm form,
                       BindingResult bindingResult) {

        //특정 필드 예외가 아닌 전체 예외
        if (form.getPrice() != null && form.getQuantity() != null) {
            int resultPrice = form.getPrice() * form.getQuantity();
            if (resultPrice < 10000) {
                bindingResult.reject("totalPriceMin", new Object[]{10000,
                        resultPrice}, null);
            }
        }

        if (bindingResult.hasErrors()) {
            log.info("errors={}", bindingResult);
            return "validation/v4/editForm";
        }

        Item itemParam = new Item();
        itemParam.setItemName(form.getItemName());
        itemParam.setPrice(form.getPrice());
        itemParam.setQuantity(form.getQuantity());

        itemRepository.update(itemId, itemParam);
        return "redirect:/validation/v4/items/{itemId}";

    }

 

위 Controller는 사용자의 요청인 수정을 담당한다. 메서드 파라미터를 보면 ItemUpdateForm 이라는 그 요청에 맞는 Model을 요청했고, 수정 내용들을 담아
DB에 반영했다. 이것은 곧 데이터를 담은 Model 객체의 변경을 의미하고, 해당 Model로부터 데이터를 가져오는 View에도 반영이 되었기 때문에 위와 같은 결과가
나온 것이다. 결과적으로 Controller는 요청을 처리하기 위해 Model을 가져와서 처리 결과를 Model과 뷰에 반영하여 사용자가 변경을 인지하도록 했다.

 

MVC 패턴을 왜 사용하는가

 

사용자가 보는 페이지, 데이터 처리, 그리고 이 2가지를 중간에서 제어하는 컨트롤러로 구성되는 하나의 애플리케이션을 만들면 각각 맡은 역할에만 집중을 할 수 있게 된다.

 

즉, 서로 분리되어 각자의 역할에 집중할 수 있도록 개발을 하고 그렇게 애플리케이션을 만든다면, 유지보수성, 애플리케이션의 확장성, 그리고 유연성이 증가하고
중복 코딩이라는 문제점 또한 사라지는 효과를 가질 수 있기 때문에 MVC 패턴을 사용한다.

 

Ref:

https://velog.io/@jybin96/Controller-Service-Repository-%EA%B0%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C#mvc-%ED%8C%A8%ED%84%B4%EC%9D%B4%EB%9E%80

 

Controller, Service, Repository 가 무엇일까?

찾아본 결과 Controller가 무엇인지 알기 전에 MVC 패턴에 대하여 먼저 아는 것이 중요합니다!MVC패턴은 Model-View-Controller의 약자로서 개발을 할 때 3가지 형태로 역학을 나누어 개발하는 방법론입니

velog.io

 

📌 스프링 MVC 구조 요약

 

아래 동작은 @Controller 컨트롤러거나 임의로 ModelAndView를 반환하여 뷰 리졸버를 사용하는 경우에 해당함

 

1. 우선, DispatcherServlet 에서 Client 요청을 받은 후 핸들러 매핑을 통해 핸들러를 조회한다.

2. 그 다음 조회된 핸들러를 처리할 수 있는 핸들러 어댑터가 핸들러 어댑터 목록에 있는지 조회한 후

3. 해당 핸들러 어댑터를 handle() 을 통해 호출한다.

4. 호출된 핸들러 어댑터는 핸들러를 호출하여

5. 결과로 ModelAndView 를 받는다.

6. ModelAndView 는 viewName 을 필드로 갖고 있는데 이것은 View 의 논리 이름으로 ViewResolver 에 넘기면

7. 실제 물리 경로를 가진 View 를 반환한다.

8. 마지막으로 View 의 render(model) 을 호출하여 화면을 렌더링할 결과가 HTML 응답으로 내려진다.

 

Spring MVC 구조

 

Reference:

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard

 

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의

웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., -

www.inflearn.com

 

'Spring' 카테고리의 다른 글

Dependency Injection(DI)과 IoC(Inversion of Control)  (0) 2023.04.27
Spring Test 관련 정리  (0) 2023.04.27
@RequestBody와 @ResponseBody  (0) 2023.04.27
Spring Boot 동작 (SSR)  (0) 2023.04.26
Controller와 RestController  (0) 2023.04.26