Servlet에서는 HttpServlet을 상속받아 doGet()이나 doPost()를 구현했지만,
Spring MVC에서는 Controller가 요청을 처리한다.
@Controller
@RequestMapping
public class FoodController {
@Controller가 붙으면 Spring이 해당 클래스를 Bean으로 등록하고, DispatcherServlet이 요청이 들어왔을 때 적절한 Controller를 찾아 실행한다.
Controller 내부에서는 @GetMapping을 이용하여 GET 요청을 처리한다.
@GetMapping
public String index(Model model) {
브라우저에서
GET /
요청이 들어오면 DispatcherServlet이 해당 메서드를 실행한다.
실행 흐름
브라우저
↓
DispatcherServlet
↓
FoodController.index()
이번 예제에서는 화면으로 전달할 데이터를 DTO에 담아 전달하였다.
public record FoodDTO(
String name,
int price
) {
}
DTO는 여러 데이터를 하나의 객체로 묶어서 전달하기 위한 객체이다.
예를 들어
FoodDTO food =
new FoodDTO("미소라멘", 12000);
객체 안에는
FoodDTO
name = 미소라멘
price = 12000
가 저장된다.
Controller에서는 Model 객체를 이용하여 View(JSP)로 데이터를 전달한다.
model.addAttribute(
"food",
new FoodDTO("미소라멘", 12000)
);
Model은 Controller와 View 사이에서 데이터를 전달하는 저장 공간이다.
동작 과정은 다음과 같다.
Controller
↓
Model
↓
JSP(View)
JSP에서는
${food.name}
${food.price}
처럼 사용할 수 있다.
데이터를 하나씩 전달하는 것도 가능하다.
model.addAttribute("name", "미소라멘");
model.addAttribute("price", 12000);
하지만 전달해야 하는 데이터가 많아질수록 코드가 복잡해진다.
DTO를 사용하면
model.addAttribute("food", foodDTO);
한 줄만으로 여러 데이터를 전달할 수 있어 유지보수가 쉬워진다.
Controller는 JSP의 전체 경로를 반환하지 않는다.
return "index";
ViewResolver가 자동으로
prefix
↓
/WEB-INF/views/
↓
index
↓
suffix
↓
.jsp
를 붙여
/WEB-INF/views/index.jsp
를 찾아 이동한다.
따라서 Controller는 JSP 위치를 알 필요 없이 View 이름만 반환하면 된다.
FoodDTO는 record를 사용하였다.
public record FoodDTO(
String name,
int price
)
record는
food.name();
food.price();
와 같이 접근할 수 있지만,
JSP의 EL(Expression Language)는
${food.name}
형태로 값을 조회하기 때문에 Getter가 필요하다.
그래서
public String getName() {
return name;
}
public int getPrice() {
return price;
}
를 직접 작성하였다.
브라우저
↓
GET /
↓
DispatcherServlet
↓
FoodController.index()
↓
FoodDTO 생성
↓
Model 저장
↓
return "index"
↓
ViewResolver
↓
/WEB-INF/views/index.jsp
↓
JSP 렌더링
↓
브라우저 응답
| Servlet | Spring MVC |
|---|---|
| HttpServlet 상속 | @Controller |
| doGet() | @GetMapping |
| request.setAttribute() | model.addAttribute() |
| RequestDispatcher.forward() | return "viewName" |
| URL 직접 처리 | @RequestMapping |
Spring MVC는 Servlet에서 직접 처리하던 대부분의 작업을 어노테이션 기반으로 자동 처리해주기 때문에 코드가 훨씬 간결해졌다.