Contents
Spring MVC
Spring MVC는 Model + View + Controller를 의미하며, 웹 사이트에서 들어오는 요청을 역할을 구분지어 관리하기 위한 기본적인 구조라고 볼 수 있다. Model은 비즈니스 로직, 데이터, DB 접근 등을 담당하고, View는 화면 단계에서 어떤 것을 보여줄지(View)에 대한 부분만 집중한다. 마지막으로 Controller는 웹 상에서의 사용자의 요청을 받아 적절한 Model을 호출하고, 결과를 View에 전송하는 중간 역할을 담당한다.
src
├─ main
│ ├─ java/com/example/demo
│ │ ├─ controller
│ │ │ └─ HomeController.java ← Controller
│ │ ├─ domain
│ │ │ └─ Member.java ← Model (DTO/Entity)
│ │ └─ service
│ │ └─ MemberService.java ← Model (비즈니스 로직)
│ └─ resources/templates
│ └─ home.html ← View (화면)
Intellij에서 Spring Boot 로 프로젝트를 생성하면, src/main/java/com/example/demo 경로로 파일을 생성해준다. 이때, demo 안에 controller와 member, service, home.html이 어떤 역할을 하는지, 그리고 어떤 코드로 작성하여야 하는지 알아보자.
Controller
Controller는 웹에서 사용자의 요청 (Enter, 화면 이동 등)이 들어왔을 때 요청에 맞는 비즈니스 로직를 수행하고 View에 데이터를 보내주는 역할을 수행한다. localhost:8080 port에 가상의 웹을 만들었다라고 가정해보자. 그러면 해당 주소로 접속했을 때, home.html로 안내하는 비즈니스 로직을 수행하는 것이다.
package com.example.demo.controller;
import com.example.demo.domain.Member;
import com.example.demo.service.MemberService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class HomeController {
private final MemberService memberService;
public HomeController(MemberService memberService) {
this.memberService = memberService;
}
@GetMapping("/") // 사용자가 "/"로 접근
public String home() {
return "home"; // View 파일 이름
}
@PostMapping("/add")
public String addMember(@RequestParam String name, Model model) {
memberService.join(new Member(name)); // Model → Service 호출
model.addAttribute("members", memberService.findAll()); // View에 데이터 전달
return "home"; // 응답할 View 이름
}
}
이때 public class의 명칭은 파일의 명칭과 동일하여야 한다. HomeController 내에 @GetMapping("/") 즉, 기본 경로로 접근했을 때에는 home.html로 안내한다. 그 이후 @PostMapping은 /add라는 추가 경로가 지정되었을 때, 요청에 맞는 Member 정보에 맞는 Service를 호출하고, 다시 home.html로 안내하는 구조다.
Model
Model은 데이터 + 비즈니스 로직 전체를 포함한다고 볼 수 있다. 단순 조회만 하는 VO (View Object), DB에 접근하여 CRUD를 담당하는 DAO (Data Acess Object), 데이터를 전달하는 역할을 담당하는 DTO (Data Transfer Object) 로 구성되어 있다.
// Member.java
package com.example.demo.domain;
public class Member {
private String name;
public Member() {}
public Member(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
// Service.java
package com.example.demo.service;
import com.example.demo.domain.Member;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class MemberService {
private final List<Member> store = new ArrayList<>();
public void join(Member member) {
store.add(member);
}
public List<Member> findAll() {
return store;
}
}
예시 코드는 아주 간단한 구조로 되어 있으며, DB를 조회할 수 있는 경우 Controller의 요청에 따른 적재된 값을 호출하는 코드로 응용할 수 있다.
View
View는 말그대로, html, xml 등의 화면을 의미한다. 화면은 구성하기 나름이며, Controller를 통해 요청에 따른 비즈니스 로직을 수행하고 값이 적재된 값을 보여주는 것도 가능하고, 기존에 적재된 값을 보여주는 화면을 만들 수도 있다.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<h1 th:text="${name}">default text</h1>
</body>
</html>
위 코드는 기존에 적재되어 있는 name이라는 entity를 보여주고, default text라고 보여주는 것을 의미한다. html이나 xml 등 뿐만 아니라 vue.js 등으로 화면을 구성하고, 각 속성에 맞는 값들을 적합한 위치에 보여줌으로써 Spring MVC 구조를 이해할 수 있다.