1. 관심사의 분리 (Separation of Concerns)
- OOP 설계 원칙(SOLID) 중 SRP(단일 책임 원칙) :
하나의 클래스/메서드는 하나의 역할(관심사)만 가져야 한다.
- 객체지향적으로 설계하려면 코드를 입력/처리/출력 역할별로 나눠야 함
- 코드의 분리
- 입력 / 처리 / 출력 분리
- 변하는 것 vs 변하지 않는 것 분리
- 공통(중복) 코드 분리
- HttpServletRequest에서 값을 꺼내는 부분은 공통 코드
→ 메서드 추출 or 스프링이 자동 바인딩 지원
- 매개변수를 컨트롤러 메서드에서 바로 선언 → 스프링이 공통으로 변환 및 주입 처리해줌
3. 출력(View)의 분리
- 변하는 것과 변하지 않는 것의 분리
- response.getWriter()로 직접 출력하는 대신, View(JSP)를 따로 두고 컨트롤러는 데이터만 Model에 담음
- View는 변하기 쉽고, Model/Controller는 상대적으로 안정적 → 변하는 것과 변하지 않는 것의 분리.
4. MVC 패턴
DispatcherServlet → Controller → Model → View → Client
- 동작 과정
- DispatcherServlet이 요청을 받고 파라미터 바인딩 처리
→ Model을 매개변수에 써주면 DispatcherServlet이 모델을 생성해서 넘겨줌
- Controller 실행 → 결과를 Model에 저장
- View에 Model 전달
→ ${} : Model의 값으로 채워짐
- 최종 결과를 클라이언트에게 응답
5. 컨트롤러 작성 방식
(1) 뷰 이름 반환
public String main(int year, int month, int day, Model model) {
model.addAttribute("yoil", getYoil(year, month, day));
return "yoil";
}
(2) void 반환
- 맵핑된 url의 끝단어가 뷰 이름 (/getYoilMVC → getYoilMVC.jsp)
(3) ModelAndView 사용
public ModelAndView main(int year, int month, int day) {
ModelAndView mv = new ModelAndView("yoil");
mv.addObject("yoil", getYoil(year, month, day));
return mv;
}
- Model과 뷰 이름을 반환
- 자주 쓰이진 않지만 가능 !
6. View 경로 설정 (공통 분리)
- servlet-context.xml에서 prefix/suffix 설정
<beans:property name="prefix" value="/WEB-INF/views/"/>
<beans:property name="suffix" value=".jsp"/>
- 컨트롤러는 뷰 이름만 반환하면 됨 → 유지보수성 ↑
7. MVC 패턴의 원리 (동작 이해)
- Reflection API를 통해 컨트롤러의 메서드와 매개변수 이름, 타입을 읽고 바인딩
- Model은 내부적으로 Map처럼 동작 (BindingAwareModelMap)
- View는 템플릿(.jsp)이고, ${key}를 Model의 값으로 치환하여 렌더링
- JSP도 결국 데이터(Model) + 템플릿(View) = 최종 HTML 구조